5 ms·
" the C-like for programmers who like C." Sounds intriguing. But then, the first thing I noticed in their example is a double-colon scope operator. I underst
by zephen 10mo ago
" the C-like for programmers who like C."
Sounds intriguing. But then, the first thing I noticed in their example is a double-colon scope operator.
I understand that it's part of the culture (and Rust, C#, and many other languages), but I find the syntax itself ugly.
I dunno. Maybe I have the visual equivalent of misophonia, in addition to the auditory version, but :: and x << y << z << whatever and things like that just grate.
I like C. But I abhor C++ with a passion, partly because of what, to me, is jarring syntax. A lot of languages have subsequently adopted this sort of syntax, but it really didn't have that much thought put into it at the beginning, other than that Stroustrup went out of his way to use different symbols for different kinds of hierarchies, because some people were confused.
Source: https://medium.com/@alexander.michaud/the-double-colon-operator-75543555fc08 https://medium.com/@alexander.michaud/the-double-colon-opera...
Think about that. The designer of a language that is practically focused on polymorphism went out of his way to _not_ overload the '.' operator for two things that are about as close semantically as things ever get (hierarchical relationships), simply because some of his customers found that overloading to be confusing. (And yet, '<<' is used for completely disparate things in the same language, but, of course, apparently, that is not at all confusing.)
I saw in another comment here just now that one of the differentiators between zig and C3 is that C3 allows operator overloading.
Honestly, that's in C3's favor (in my book), so why don't they start by overloading '.' and get rid of '::' ?
- nathan_compton 10mo agoAs a long time lisper I can't stand how much syntax languages have and I think of excess syntax as a sign of a childish mind, but what can you do?
- zephen 10mo agoAs I get older, I realize that everybody's sweet spot is a little different. Lisp and APL both have their adherents. I personally find a bit more syntax than lisp to be nice. Occasionally I long for the homoiconicity of lisp; otoh, many of the arguments for it fall flat with me. For example, DSLs -- yeah, no, it's hard enough to get semi-technical people to use DSLs to start with, never mind lisp-like ones.
- HarHarVeryFunny 10mo agoIt's horses for courses, right? Pick the right language for the job. LISP was designed for 60's era GOFAI, designed for that with code not differentiated from data, but a COBOL or FORTRAN even BASIC programmer would presumably (and justifiably from the perspective of those typical use cases) regard LISP as the toy/unserious language.
- HarHarVeryFunny 10mo agoNamespaces to me are more about naming conflict resolution and code readability, and I think of them more as prefixes to namespace member names, as opposed to those member names being part of a hierarchy. It also helps code readability to know that a::b is referring to a namespace, without having to go lookup the definition of "a", while a.b is a variable access.
- zephen 10mo ago> Namespaces to me are more about naming conflict resolution and code readability, and I think of them more as prefixes to namespace member names, as opposed to those member names being part of a hierarchy. That's a perspective. Are we talking about the 'bar' that comes from 'foo' or are we talking about the 'bar' that comes from 'baz'? But another perspective is that 'foo' is important and provides several facilities that are intimately related to foo, so 'bar' is simply one of the features of foo. > It also helps code readability to know that a::b is referring to a namespace For you, perhaps. As someone who reads a lot of Python, I don't personally find this argument persuasive.
- HarHarVeryFunny 10mo agoRight - I just wanted to point out that not everyone is going to conceptualize namespaces and members, the same as structs and members, as both being about "hierarchy". I'm generally of the camp that code is written once, read many times, and that anything that adds to readability is therefore a win.
- zephen 10mo ago> anything that adds to readability is therefore a win. Right, the entire question is whether '::' ever adds to readability. For me, it's a huge negative. Obviously, YMMV.
- lerno 10mo agoTwo reasons, the second being the important: (1) If I read "io.print", is this "the print function in the module io" or "the print method for the variable io". There tends to be an overlap in naming here so that's a downside (2) parsing and semantic checking is much easier if the namespace is clear from the grammar. In particular, C3's "path shortening", where you're allowed to write `file::open("foo.txt")` rather than having to use the full `std::io::file::open("foo.txt")` is only made possible because the namespace is distinct at the grammar level. If we play with changing the syntax because it isn't as elegant as `file.open("foo.txt")`, we'd have to pay by actually writing `std.io.file.open("foo.txt")` or change to a flat module system. That is a fairly steep semantic cost to pay for a nicer namespace separator. I might have overlooked some options, if so - let me know.
- alcover 10mo ago> (1) If I read "io.print", is this "the print function in the module io" or "the print method for the variable io" I don't see the issue. Just look up the id ? Moreover, if modules are seen as objects, the meaning is quite the same. > checking is much easier if the namespace is clear from the grammar. Again (this time by the checker) just look up the symbol table ?
- lerno 10mo agoLet's say you have find foo::bar(), then we know that the path is <some path>::foo, the function is `bar` consequently we search for all modules matching the substring ::foo, and depending on whether (1) we get multiple matches (2) we only get a match that is not properly visible (3) we get a match that isn't imported, (4) we get no match or (5) we get a visible match, we print different things. In the case 1-4, we give good errors to allow the user to take the proper action. If instead we had foo.bar(), we cannot know if this is the method "bar" on local or global foo, or a function "bar()" in a path matching the substring "foo". Consequently we cannot properly issue 4, since we don't know what the intent was. So far, not so bad. Let's say it's instead foo::baz::bar(). In the :: case, we don't have any change in complexity, we simply match ::foo::baz instead. However, for foo.baz.bar(), we get more cases, and let us also bring in the possibility of a function pointer being invoked: 1. It is invoking the method bar() on the global baz is a module that ends with "foo" 2. It is calling a function pointer stored in member bar on the global variable baz is a module that ends with "foo" 3. It is calling the function bar() in a module that ends with "foo.baz" 4. It is calling the function pointer stored in the global bar in a module that ends with "foo.baz" 5. It is invoking the method bar on the member baz of the local foo 6. It is calling a function pointer stored in the member bar in the member baz of the local foo This might seem doable, but note that for every module we have that has a struct, we need to speculatively dive into it to see if it might give a match. And then give a good error message to the user if everything fails. Note here that if we had yet another level, `foo.bar.baz.abc()` then the number of combinations to search increases yet again.
- baranul 10mo agoIt definitely is possible, because languages like Vlang (for example), are able to use '.' instead of '::'. Always saw this as language creator preference, versus any inescapable technical reason.