Hacker News new | past | comments | ask | show | jobs | submit | Sandman's comments login

Wouldn't it be more explicit if there was a designated keyword that objects could use to access their own members instead of implicitly assuming that any first argument to a method is a reference to them, only called 'self' by convention?


> Wouldn't it be more explicit if there was a designated keyword that objects could use to access their own members

Not really. You end up implicitly injecting some value into local namespaces instead of having a function that takes an argument.

The implicitness of methods working differently than normal functions > the implicitness of classes passing a first argument to methods.


Should super then also be a method argument?


Honestly, I think it would have made some amount of sense to make super a method defined on the base object so that

    def __init__(self, x, y):
        self.super(x, y)
would be the convention. There may be some infra issue with this (and in general, `super` has to be kind of magical no matter how you handle it). But yes, in general I can vibe with "super is too implicit".


Ruby generally (I think? I haven't seen much of Ruby code) uses "@" instead of "self.", and "@@" instead of "ParticularClassName." (btw, "self.__class__" doesn't cut it), and it seems to produce no namespace pollution.


I don't think this is a naming issue at all. In the provided example, 'Accuracy' is the correct name for the parameter, as that's what the parameter represents, accuracy. The fact that accuracy should be given as a value in an interval from 0 to 1 should be a property of parameter type. In other words, the parameter should not be a float, but a more constrained type that allows floats only in [0,1].

EDIT: Some of you asked what about languages that don't support such more constrained types, so to answer all of you here: different languages have different capabilities, of course, so while some may make what I proposed trivial, in others it would be almost or literally impossible. However, I believe most of the more popular languages support creation of custom data types? So the idea (for those languages at least) is quite simple - hold the value as a float, but wrap it in a custom data type that makes sure the value stays within bounds through accessor methods.


Unfortunately, creating a constrained type like this isn't easy (or even doable) in all programming languages.

Fortunately, my preferred programming language, Raku, makes creating this sort of subset trivially easy[0]:

  subset UnitInterval of Real where 0 ≤ * ≤ 1
[0]: https://docs.raku.org/language/typesystem#index-entry-subset...


In C, I wonder if you could do something with functions and macros?

Say you need to represent velocity in a transportation simulation. You could have a function, velocity, that looks like this:

  double velocity(double v, char * of_what)
You use it to wrap constrained values. E.g.,

  double v_jogger = velocity(8.0, "human");
  double v_car = velocity(65.0, "city car");
velocity() simply returns the first argument, after doing validity checking based on the second argument.

You probably couldn't reasonably use this everywhere that you would use actual constrained types in a language that has them, but you could probably catch a lot of errors just using them in initializers.


The problem you'd have is that doing any operations on such a value could take it outside the bounds of the "type".


In Swift you can achieve this with Property Wrappers:

  @Clamping(0...14) var pH: Double = 7.0
https://nshipster.com/propertywrapper/#implementing-a-value-...


Is there a difference between ≤ and <= in Raku? Curious why you used ≤ in your example.


They're equivalent, Raku defines both Ascii compatible and Unicode names for typical operators. I expect they used ≤ because it looks nicer.


Yep, correct on both counts


I think this is the best answer.

This got me thinking: What about a situation where the accuracy is given in a real-life unit. For example, the accuracy of a GPS measurement, given in meters. I've sometimes used names like 'accuracyInMeters' to represent this, but it felt a bit cumbersome.

Edit: Thinking more about it, I guess you could typealias Float to Meters, or something like that, but also feels weird to me.


More complex type systems absolutely support asserting the units of a value in the type system. For example, here's an implementation of SI types in C++: https://github.com/bernedom/SI


I've used "fraction" for this purpose .. but that isn't general enough. In fact a convention I've used for nearly 2 decades has been varName_unit .. where the part after the underscore (with the preceding part being camel case) indicates the unit of the value. So (x_frac, y_frac) are normalized screen coordinates whereas (x_px, y_px) would be pixel unit coordinates. Others are like freq_hz, duration_secs and so on.


I usually do the "inMeters" thing.

Another thing you can do is define a "METER" constant equal to 1. You can then call your function like this: func(1.5 * METER), and when you need a number of meters, you can do "accuracy / METER". The multiplication and division should be optimized away.

Good thing about that is that you can specify the units you want, for example you can set FOOT to 0.3048 and do "5. * FOOT" and get back your result in centimeters by doing "accuracy / CENTIMETER". The last conversion is not free if the internal representation is in meter but at least, you can do it and it is readable.

If you are going to use such distances a lot, at least in C++, you can get a bit of help from the type system. Define a "distance" class operator overloads, constants and convenience functions to enforce consistent units. Again, the optimizer should make it not more costly than using raw floats if that's what you decide to use as an internal representation.



Some languages provide more than just an alias. Eg Haskell lets you wrap your Float in a 'newtype' like 'GpsInMeters'.

The newtype wrapper doesn't show up at runtime, only at compile time. It can be set up in such a way that the compiler complains about adding GpsInMeters to GpsInMiles naively.


That's what unboxed tagged types are for. Floats (e.g.) at runtime, but with compile time restrictions.


While true, if your language doesn’t support such a type, then the burden for such a name goes to the parameter, does it not?


> While true, if your language doesn’t support such a type

You'd be surprised where the support is. In C#, you would declare a struct type with one read only field of type double, and range validation (x <= x <= 1) in the constructor.

this is the "value object" pattern. http://wiki.c2.com/?ValueObject

Yes there's a bit of boilerplate - especially since you might want to override equality, cast operators etc. But there is support. And with a struct, not much overhead to it.


I don't think runtime validation is that special. You can bend most languages into this pattern one way or another. The real deal is having an actual compile-time-checked type that resembles a primitive.


Actually what I want is just the reading experience of seeing

"public Customer GetById(CustomerId id)" instead of "public Customer GetById(string id)" when only some strings (e.g. 64 chars A-Z and 1-9) are valid customer ids.

Compile-time validation would be ideal, but validation at the edges, well before that method, is good enough.


See: "Primitive Obsession" https://wiki.c2.com/?PrimitiveObsession

Usually cured by using Value objects. I wish this done more in OO code.

Could it be better supported in these languages? Yes, for sure. But is it true that "these language do not support such a type" at all? No.


Joel, on the original purpose of Hungarian notation:

https://www.joelonsoftware.com/2005/05/11/making-wrong-code-...


Very insightful article. I wasn't aware of "Apps Hungarian", which indeed seems like a much better idea of the redundant "System Hungarian".


Usually that would go to the documentation of the parameter, plus a run-time assertion to check that received values are valid.


But the best documentation is the code itself that is documentation. I mean, well that’s kind of a cliché, but names can carry a lot of meaning.


Or you could approach it another way, store the data using the full range of the system float type and normalize it to [0,1] through accessor methods.

Can float types even support 0, 1 inclusive? You just can't represent natural numbers like that with floats...


The main issue with techniques such as this, which are certainly easy to do, is that if it’s not in the type system and therefore not checked at compile time, you pay a run time cost for these abstractions.


You can't represent the interval from 0 to 1 inclusive without significant run time cost just because of the way floats work.


Great that you like typed languages, and ones that allow for such constrained/dependent typing as well.

It seems disingenuous to me to suggest that anyone using other languages do not have this problem. And really, there are quite a few languages to not have this form of typing, and even some reasons for a language to not want this form of typing.

So please, don't answer a question by saying "your questions is wrong" it is condescending and unhelpful.


Equally condescending is saying "It's great that you like X, but I don't so I'm going to ignore the broader point of your argument."

The point remains that the fact a given parameter's valid values are [0,1] is not a function of it's name. You can check the values within the method and enter various error states depending on the exact business rules.


"your question is wrong" is indeed unhelpful, especially as a direct response to someone asking a question.

"here is what seems like a better question" is helpful, especially in a discussion forum separate from the original Q/A.

But if "here is what seems like a better question" is the _only_ response or drowns out direct responses, then thats still frustrating.

> condescending

As a man who sometimes lacks knowledge about things, when I ask a question, please please please err on the side of condescending to me rather than staying silent. (No, I don't know how you should remember my preferences separately from the preferences of any other human)


I'm genuinely sorry if I came across as condescending, that was not my intention at all.

I merely wanted to point out that, in my opinion, this property should be reflected in parameter type, rather than the name. Just like, if we wanted a parameter that should only be a whole number, we wouldn't declare it as a float and name it "MyVariableInteger" and hope that the callers would only send integers.

You mentioned that there are quite a few languages that do not permit what I proposed, would you mind specifying which ones exactly? The only one that comes to my mind is assembly?


So, then the user calling the library with foo(3.5) will get a runtime error (or, ok, maybe even a compile time error).

To avoid that, you need to document that the value should be between 0 and 1, and you could do that with a comment line (which the OP wanted to avoid), or by naming the variable or type appropriately: And that takes us back to the original question. (Whether the concept is expressed in the parameter name or parameter type (and its name) is secondary.)


> So, then the user calling the library with foo(3.5) will get a runtime error (or, ok, maybe even a compile time error).

I'm not sure I understand this. See below, but the larger point here is that the type can never lie -- names can and often do because there's no checking on names.

I think what is being proposed is something similar to

    newtype Accuracy = Accuracy Float
and then to have the only(!) way to construct such a value be a function

    mkAccuracy :: Float -> Maybe Accuracy
which does the range checking, failing if outside the allowable range.

Any functions which needs this Accuracy parameter then just take a parameter of that type.

That way you a) only have to do the check at the 'edges' of your program (e.g. when reading config files or user input), and b) ensure that functions that take an Accuracy parameter never fail because of out-of-range values.

It's still a runtime-check, sure, but but having a strong type instead of just Float, you can ensure that you only need that checking at the I/O edges of your program and absolute assurance that any Accuracy handed to a function will always be in range.

You can do a similar thing in e.g. C with a struct, but unfortunately I don't think you can hide the definition such that it's impossible to build an accuracy_t without going through a "blessed" constructor function. I guess you could do something with a struct containing a void ptr where only the implementation translation unit knows the true type, but for such a "trivial" case it's a lot of overhead, both code-wise and because it would require heap allocations.


You're solution is the ideal one and safest, although in the interest of maximum flexibility since the goal here seems more documentative than prescriptive, it could also be as simple as creating a type alias. In C for example a simple `#define UnitInterval float`, and then actual usage would be `function FuncName(UnitInterval accuracy)`. That accomplishes conveying both the meaning of the value (it represents accuracy) and the valid value range (assuming of course that UnitInterval is understood to be a float in the range of 0 to 1).

Having proper compile time (or runtime if compile time isn't feasible) checks is of course the better solution, but not always practical either because of lack of support in the desired language, or rarely because of performance considerations.


That's fair, but I do personally have a stance that compiler-checked documentation is the ideal documentation because it can never drift from the code. (EDIT: I should add: It should never be the ONLY documentation! Examples, etc. matter a lot!)

There's a place for type aliases, but IMO that place is shrinking in most languages that support them, e.g. Haskell. With DerivingVia, newtypes are extremely low-cost. Type aliases can be useful for abbreviation, but for adding 'semantics' for the reader/programmer... not so much. Again, IMO. I realize this is not objective truth or anything.

Of course, if you don't have newtypes or similarly low-cost abstractions, then the valuation shifts a lot.

EDIT: Another example: Scala supports type aliases, but it's very rare to see any usage outside of the 'abbreviation' use case where you have abstract types and just want to make a few of the type parameters concrete.


so, basically hungarian notation


'disingenuous' seems to imply that it was an intentional omission. -- which i doubt it was.

you have a very valid point but it would come across even more effectively without that part, i believe.


Sure, such other languages have the problem too, it's just that they are missing the best solution. It's possible for a solution to be simultaneously bad and the best available.


Stan, a probabilistic programming language where this thing comes up a lot, makes it easy to declare such constrained parameters:

  real<lower = 0, upper = 1> accuracy;


yeah, right, so what do you call such a type? I believe that is the actual question.


The question was about the parameter name, though. The correct answer seems to be:

    function FuncName(UnitInterval accuracy)


    function FuncName(NormalizedFloat accuracy)
In languages with operator overloading you can make NormalizedFloat a proper class with asserts in debug version and change it to an alias of float in release version.

Similarly I wonder why gemoetry libraries don't define separate Point class and Vector class, they almost always use Vector class for vectors and points.

I understand math checks out, and sometimes you want to add or multiply points, for example:

    Pmid = (P0 + P1) / 2
    
But you could cast in such instances:

    Pmid = (P0 + (Vector)P1)/ 2
And the distinction would surely catch some errors.

    Point - Point = Vector
    Point + Point = ERROR
    Vector +/- Vector = Vector
    Point +/- Vector = Point
    Point * scalar = ERROR
    Vector * scalar = Vector
    Point */x Point = ERROR
    Vector * Vector = scalar
    Vector x Vector = Vector


UnitInterval seems to contains an interval, not a single float. I don't think it's a very good name.

UnitIntervalNumber would be better, but it's too long. Something like UnitNumber or UnitFloat could maybe work.


After reading this reply twice, I realised you are right and UnitInterval type indicates an interval object instead of a single scalar number.

I have actually used intervals, and should have realised this sooner. But I just had my first cup of coffee...


Yes, UnitInterval is a really bad name for a single number. Astonishingly, it has 30 upvotes on SO.


I work in games where these values are extremely common and 'accuracy' wouldn't be very descriptive in a lot of circumstances: explosion radius falloff damage, water flow strength, positional/rotational lerps or easing, and more.

I wish I were commenting here with an answer, but I don't have one. "brightness01" is a common naming convention for values of this type in computer graphics programming, but niche enough that it got raised in review comments by another gameplay programmer.


That's a very good observation. We still could need a (new) term for this common type. Maybe floatbit, softbit, qubit(sic), pot, unitfloat, unit01 or just unitinterval as suggested?

This begs an interesting tangential question: Which programming languages allow such resticted intervals as types?

type percentage:=int[0,100] type hexdigit:=int[0,15] …

since this might be overkill, sane programming languages might encourage assert statements inside the functions.


floatbit is good starting idea, but maybe too long to be catchy. How about a flit?


I think this is right, but it's still IMO basically a natural language semantics issue. For instance in haskell (which has a pretty advanced static type system), I would still probably be satisfied with:

  -- A float between 0 and 1, inclusive.
  type UnitInterval = Float
  
  foo :: UnitInterval -> SomeResultPresumably
  foo accuracy = ...
i.e. I think the essential problem in the SO question is solved, even though we have no additional type safety.

A language without type synonyms could do just as well with CPP defines


Looks like it’s actually possible to string something like this together in Python; custom types are of course supported, and you can write a generic validation function that looks for your function’s type signature and then asserts that every UnitInterval variable is within the specified bounds.

You’d have to decorate/call manually in your functions so it’s not watertight, but at least it’s DRY.


I agree that it's a question of type: what would you call that type though?

I propose "pun" - proportion of unity, or "p(er) un".


Between0And1Inclusive

I like verbosity!

Or use a dependent type language. Maybe Idris? Then something like Between(0,1) I guess.


Nothing wrong with the name ZeroToOneInclusive. Seems like a great type to have around, and a great name for it. UnitFloat or UnitIntervalFloat or other ideas ITT are cuter but not much clearer.


I'm envisioning a programming language in which variable names and type names can become one.

So instead of

func call(Person person){} you just have func call(person){}

where person is a known type AND the variable name.

In that scenario 'accuracy' would be a type with known value between 0 and 1.


Combine with the JS/TS syntax sugar for objects and

{person}

Is an object person with key person and value person of type Person


what if you have to deal with two persons?


In that case you could have the signature

func call(person#1 person#2){}


Wouldn't it be better if we could give meaningful names instead of 1 and 2?

    function call(person#sender person#receiver)
And at that point we're back to the square one, just remove the # :)


>However, I believe most of the more popular languages support creation of custom data types?

No, most don't, except if you go into building custom classes.


So, most don't support custom types unless you...use the mechanism they have for defining a custom type?

That seems a very elaborate way to say “No" when the answer is really “Yes”.


It's a succint way to say "No, not types that will automatically work as primitive types (which normally the variable passed for 0 to 1 would be), and that will work with numeric operators".

Or in other words, a succint way to say "Technically yes, but practically useless, so no".


I would simply put this in the description of the parameter. That’s what it is for; after all, not every constraint is computable or easy to check.


But what do you name the variable in the languages that don't support such a constrained type feature (the majority of them)?


Object-oriented languages have equivalent constructs, so I would say that this is doable in the vast majority of languages in common use:

https://news.ycombinator.com/item?id=24374372

http://wiki.c2.com/?ValueObject


Is there an example, in any language, showing how you would represent this at the type level? I can’t see how you would do it.


In Elm (and many other languages, I assume, I'm just most familiar with Elm) there's a pattern called "opaque data type". [0] You make a file that contains the type and its constructor but you don't export the constructor. You only export the getter and setter methods. This ensures that if you properly police the methods of that one short file, everywhere else in your program that the type is used is guaranteed by the type system to have a number between zero and one.

-- BetweenZeroAndOne.elm

module BetweenZeroAndOne exposing (get, set)

type BetweenZeroAndOne = BetweenZeroAndOne Float

set : Float -> BetweenZeroAndOne set value = BetweenZeroAndOne (Basics.clamp 0.0 1.0 value)

get : BetweenZeroAndOne -> Float get (BetweenZeroAndOne value) = value

[0] https://en.wikipedia.org/wiki/Opaque_data_type#:~:text=In%20....


You would just make the constructor return a possible error if it's not in range, or maybe some specialty constructors that may clamp it into range for you so they always succeed.

It's the same question of, how can you convert a string to a Regexp type if not all strings are valid Regexps?


Right, so there's no way to do this:

> In other words, the parameter should not be a float, but a more constrained type that allows floats only in [0,1]

It's a value check, not a type check.


Typescript:

    type NormalisedFloat = number
Admittedly it doesn't add any actual value checking, but it does convey the information when you look at the parameter definition.


Even if you could created constrained types like this, don't you still need to worry about what to call it?


I don’t understand why having the ability to describe such a type removes the need to be able to name it.



Croatian here. You're correct, if you only said the word "spomenik" to anybody from former Yugoslavia, they wouldn't be able to distinguish whether you're talking about precisely those monuments built after WW2, or any other monument built before or after the communist era. Or even, say, Washington monument (In Croatian it's literally called "Washingtonov spomenik"). The word "spomenik" means "a monument" and just that. I was actually surprised to learn that in English the word refers to monuments from a particular location and particular era.


Well, there are other examples - to me, Bohemians are my nation, to English people, "bohemian" describes behavior that used to be seen here (and way overblown in catholic-driven news sources at the time - Prague people were protestant) during the Middle Ages


then there is no point switching

Why not? Your chances of choosing the correct door were 1 in 3 from the start. That doesn't change with the fact that the host opens the doors at random.


Sorry for the late reply, but if you look at the original article on GitHub I explore that scenario in the code. The answer is that if Monty randomly opens a door then the contestant automatically loses 1/3 of the time before given a chance to switch.


That's what the GP said. In reality, the host doesn't open the door at random. They know which door hides the car and avoid opening it. That's why switching the doors doubles your chances of finding it (because the host has already eliminated one of the goat doors).


Your chance was 1 in 3 yes, but if the host can randomly open the car door, there is a chance of 1 in 3 of that happening, leaving only 1 in 3 chwnce of switching being legal and useful.


If you only ever offered the players to switch if they picked the car, they'd soon realize this and never switch when they're offered this chance. Also, players that picked a goat at first would have no chance of winning the car.


That's assuming players knows about the other players, which is not specified in the problem description. It is not even specified if the same game is played several time with the same rules.

Given the description from the article:

> Suppose you're on a game show, > and you're given the choice of > three doors: Behind one door is > a car; behind the others, goats. > You pick a door, say No. 1, and > the host, who knows what's behind > the doors, opens another door, > say No. 3, which has a goat. He > then says to you, "Do you want > to pick door No. 2?" Is it to > your advantage to switch your > choice?

I'd say, no, it is not to my advantage because I'd think the host would only ask me to switch if I had taken the "right" choice and want to make me lose. Unless I knew that the host always ask if one wants to change, in which case the paradox indeed apply.


Game show regulations would not allow that behavior. The problem assumes a typical game show in western media so the reader should assume the player knows all the rules governing the host’s behavior, which you can see in the other discussions.


Cool, I didn't know about that one! I'm going to check it out, thanks for the link!


> the ability to defend yourself against a tyrannical dictatorship made sense until the government developed better technology, now it's pointless so just give up your guns?

Basically, yes. Do you honestly think people would have any chance against probably the most powerful army in the world? Sure, they could try fighting a guerilla warfare, they'd even inflict some casualties against the enemy but it's unlikely that in the end they'd succeed against an army that is professional, highly skilled, better equipped, has better offensive and defensive capabilities, knows a lot more about tactics and logistics and has trained for this type of situation on a daily basis.

> Are they going to destroy their own infrastructure?

Would they even consider it their own infrastructure? Or would they consider it infrastructure currently held by rebels, which needs to be either seized or destroyed?

> Do you think the real men and women of the military would follow orders to destroy its own hometowns and families?

I suspect a lot of them would destroy towns if they we're told that these are now enemy bases. This has been repeated in many parts of the world throughout the history, even recent one. If they wouldn't, they'd be defectors and it really wouldn't matter whether the war was fought with modern weapons or sticks and stones.


It wouldn't work as you imagine because it would be far too expensive for the government. In the Middle East it works out because none of our infrastructure is affected by the war; so our GDP, and thus tax revenue, is still strong. In a civil war where the government is bombing its own infrastructure the cost for each kill will skyrocket and the effect on the economy will be catastrophic. Fighting a defensive war is immeasurably cheaper than an offensive war as the defenders value the lives of their soldiers much less than the offenders do. Also keep in mind that a rebel faction could very easily sabotoge critical infrastructure like electricity which would be very difficult to repair in a timely manner.

Relying on very expensive advanced weaponry is the modern equivalent of relying on mercenaries, and Machiavelli told us why mercenaries are bad.


>>>Do you honestly think people would have any chance against probably the most powerful army in the world?

You are placing waaaay too much faith in technology. Look at the Saudis: one of the worlds highest military budgets, and stockpiles of first-rate western hardware.....they are getting absolutely routed by Houthis, who run up desert mountains with just sandals, an AK, and a mouth full of stimulants.

>>>Sure, they could try fighting a guerilla warfare, they'd even inflict some casualties against the enemy but it's unlikely that in the end they'd succeed against an army that is professional, highly skilled, better equipped, has better offensive and defensive capabilities, knows a lot more about tactics and logistics and has trained for this type of situation on a daily basis.

What is the data that is driving you to this conclusion? Are you ignoring pretty much every counter-insurgency experience the US has had for the last 50 years? [2][3]

>>>I suspect a lot of them would destroy towns if they we're told that these are now enemy bases.

I suspect you don't know actual American military personnel very well, especially officers and NCOs, and how seriously we take the Laws of Warfare, AND the Constitution.

[1]https://www.snafu-solomon.com/2019/09/pics-of-houthi-rebels-...

[2]https://foreignpolicy.com/2019/02/05/why-america-lost-in-afg...

[3]https://www.foreignaffairs.com/articles/united-states/2015-0...


> I suspect you don't know actual American military personnel very well, especially officers and NCOs, and how seriously we take the Laws of Warfare, AND the Constitution.

You're right, I don't. But, if Americans don't need to fear that they'll have to fight the US Army, why have the 2nd amendment at all? Who would they need to protect themselves against?


Rioters, rogue police, vigilantes, rogue militas, nazis, militaries commanded by those that are not upholding the constitution. Honestly your argument makes it more sensible that we should open up restrictions and allow more lethal weapons.


> Sure, they could try fighting a guerilla warfare, they'd even inflict some casualties against the enemy but it's unlikely that in the end they'd succeed against an army that is professional, highly skilled, better equipped, has better offensive and defensive capabilities, knows a lot more about tactics and logistics and has trained for this type of situation on a daily basis.

Have you heard of the Viet Cong?


> Have you heard of the Viet Cong?

The one that got basically wiped out despite foreign backing (though the regular army that was their most direct supporter—the North Vietnamese Army—intervened and ultimately won the war after they were crushed)? Yeah, heard of them.

They kind of prove (or at least demonstrate) the point the grandparent post was making, though.


A student came to his master.

"Great master" he said "You are wise and know many things. But tell me this: What is the sound of one hand clapping?"

The master slapped him.

At that moment, the student attained enlightenment.


I'd wager Dickens didn't have anybody stand over his shoulder, watching if he's delivering page after page at a fast enough rate.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: