Qualified name syntax/dot`.`tightfix
Quote from AntC on July 9, 2025, 10:24 amHmm. I suspect 'Empirical Investigation's are largely an exercise in confirming prejudices. Early in my programming career I got told RPG is intuitive. (Must be some sense of "intuitive" I wasn't previously aware of.)
I don't find Java to be cryptic. (It's TECO that started the 'indistinguishable from line noise' meme.) I do find Java so verbose that the program's logic gets smothered with administrivia. Haskell was refreshing in comparison. What attracted me was it got the balance about right in the scale of elegant -> terse -> cryptic. (At least when I encountered it around 2010. These days that's not so true.)
a field name needs to have the same datatype whatever record it is in
You'll find there's at least one TTM-aligned environment takes that approach -- for attributes appearing in a given schema. It seems not unreasonable that
SNo
'means' the same thing everywhere, so is the same type. (I hate schemas that have anid
in every table, and aname
in many tables -- even though they might be same-lengthString
s, a Supplier Name is not comparable to a Product Name to a Customer Name.)Why you'd restrict a field name to only one record type has never made sense. There's a kind of historical explanation in that Haskell was at first very timid about anything polymorphic/that is, that was spread across many (record) types. But the explanation is not a justification nor motivation. Haskell/functional programming goes in bigly for partial application. You might have a routine that goes through a database uplifting a
qty
field by 5%. If you don't know whether that'sInt
orFloat
orMoney
or what, neither do you know what record type(s) it applies to, the program that calls the routine is very hard to typecheck statically.they didn't come up with an alternative syntax when the
.
was takenI think the history was (I wasn't there at the time/neither were design decisions closely documented)
.
as function compose arrived first. [**].
like all operators was allowed to be written tightfix:qty+1
;round.double
- Then a module/namespace system arrived, using qualified
Module.Sub.foo
.- That was thought not to be too awkward, because (sub)Module names must begin upper-case; components lower.
- Already there were corner cases:
Just.double
(whereJust
builds a data item so is kinda a function) clashes with dot-qualified, so can't be written tightfix, insteadJust . double
; whereas tightfixdouble.Just
is accepted.- There were other uses of
.
as not operator: most obviously as decimal point with tightfix digit both sides3.14e0
;forall a. a -> Maybe a
is the fully-spelled-out type signature forJust
. You can tightfix or space-surround the.
as you choose.- That would have been the point to say
.
is not just an 'ordinary' operator, can never be written titghtfix qua operator. (If you want to write compose tightfix, define some other glyph as compose.)- That nettle wasn't grasped, so there grew up an idiom of building higher-order functions as
player.position.xcoord
, treated as a conceptual unit/qualified name.- [**] It could have been worse: Standard ML uses lower-case
o
for compose, because it looks like the math symbol. But that's an alpha/can't be an operator in Haskell except by special pleading; and anyway can't be written tightfix between other alpha namesroundodouble
.
Quote from Erwin on July 7, 2025, 7:49 pm... prevent the language from embracing the RM in full.
In this case the RM is nowhere near: we want the flavour of OOP
struct.component
. We'd get better conceptual alignment with the RM as an unintended side-effect.
Hmm. I suspect 'Empirical Investigation's are largely an exercise in confirming prejudices. Early in my programming career I got told RPG is intuitive. (Must be some sense of "intuitive" I wasn't previously aware of.)
I don't find Java to be cryptic. (It's TECO that started the 'indistinguishable from line noise' meme.) I do find Java so verbose that the program's logic gets smothered with administrivia. Haskell was refreshing in comparison. What attracted me was it got the balance about right in the scale of elegant -> terse -> cryptic. (At least when I encountered it around 2010. These days that's not so true.)
a field name needs to have the same datatype whatever record it is in
You'll find there's at least one TTM-aligned environment takes that approach -- for attributes appearing in a given schema. It seems not unreasonable that SNo
'means' the same thing everywhere, so is the same type. (I hate schemas that have an id
in every table, and a name
in many tables -- even though they might be same-length String
s, a Supplier Name is not comparable to a Product Name to a Customer Name.)
Why you'd restrict a field name to only one record type has never made sense. There's a kind of historical explanation in that Haskell was at first very timid about anything polymorphic/that is, that was spread across many (record) types. But the explanation is not a justification nor motivation. Haskell/functional programming goes in bigly for partial application. You might have a routine that goes through a database uplifting a qty
field by 5%. If you don't know whether that's Int
or Float
or Money
or what, neither do you know what record type(s) it applies to, the program that calls the routine is very hard to typecheck statically.
they didn't come up with an alternative syntax when the
.
was taken
I think the history was (I wasn't there at the time/neither were design decisions closely documented)
.
as function compose arrived first. [**].
like all operators was allowed to be written tightfix:qty+1
;round.double
- Then a module/namespace system arrived, using qualified
Module.Sub.foo
. - That was thought not to be too awkward, because (sub)Module names must begin upper-case; components lower.
- Already there were corner cases:
Just.double
(whereJust
builds a data item so is kinda a function) clashes with dot-qualified, so can't be written tightfix, insteadJust . double
; whereas tightfixdouble.Just
is accepted. - There were other uses of
.
as not operator: most obviously as decimal point with tightfix digit both sides3.14e0
;forall a. a -> Maybe a
is the fully-spelled-out type signature forJust
. You can tightfix or space-surround the.
as you choose. - That would have been the point to say
.
is not just an 'ordinary' operator, can never be written titghtfix qua operator. (If you want to write compose tightfix, define some other glyph as compose.) - That nettle wasn't grasped, so there grew up an idiom of building higher-order functions as
player.position.xcoord
, treated as a conceptual unit/qualified name. - [**] It could have been worse: Standard ML uses lower-case
o
for compose, because it looks like the math symbol. But that's an alpha/can't be an operator in Haskell except by special pleading; and anyway can't be written tightfix between other alpha namesroundodouble
.
Quote from Erwin on July 7, 2025, 7:49 pm... prevent the language from embracing the RM in full.
In this case the RM is nowhere near: we want the flavour of OOP struct.component
. We'd get better conceptual alignment with the RM as an unintended side-effect.
Quote from tobega on July 10, 2025, 2:18 pmInteresting. If Haskell had chosen to require the same type for a particular field name, I suppose everything would have worked out neatly by ad-hoc polymorphism on the accessor functions.
Intuitive is very much in the eye of the beholder. In this case, they did manage to scare up some non-programmers which were their main focus, and also some programmers, so I suppose there is something to it. At least the Quorum language that it resulted in seems to be easy enough for blind children to use.
I always loved programming in Java (still do), but you get looked at strangely these days if you admit it. It's gotten even better with records and pattern-matching.
I exaggerated the "line noise". What they showed was that a beginner could understand any randomly generated symbol almost as well as the symbols chosen for Java syntax. The readability in Java programs comes from naming, anyway.
Interesting. If Haskell had chosen to require the same type for a particular field name, I suppose everything would have worked out neatly by ad-hoc polymorphism on the accessor functions.
Intuitive is very much in the eye of the beholder. In this case, they did manage to scare up some non-programmers which were their main focus, and also some programmers, so I suppose there is something to it. At least the Quorum language that it resulted in seems to be easy enough for blind children to use.
I always loved programming in Java (still do), but you get looked at strangely these days if you admit it. It's gotten even better with records and pattern-matching.
I exaggerated the "line noise". What they showed was that a beginner could understand any randomly generated symbol almost as well as the symbols chosen for Java syntax. The readability in Java programs comes from naming, anyway.
Quote from Darren Duncan on July 11, 2025, 12:29 amI can see where people are coming from calling languages that have a much richer base syntax with lots of symbols like Perl as line noise, since it is more cognitive effort to learn the base syntax.
However, one of the key benefits of Java and C# is that its base syntax is much smaller, and mostly based on English words with few symbols, and so it is inherently a lot quicker for someone new to read and understand what Java or C# code does.
I can see where people are coming from calling languages that have a much richer base syntax with lots of symbols like Perl as line noise, since it is more cognitive effort to learn the base syntax.
However, one of the key benefits of Java and C# is that its base syntax is much smaller, and mostly based on English words with few symbols, and so it is inherently a lot quicker for someone new to read and understand what Java or C# code does.
Quote from AntC on July 11, 2025, 12:44 amQuote from tobega on July 10, 2025, 2:18 pm..., I suppose everything would have worked out neatly by ad-hoc polymorphism on the accessor functions.
Hehe, bless you. The field (content) might have polymorphic type -- indeed might itself be a nested record. So there was a ~2015 proposal from a top honcho that got banjaxed/defeated by too much polymorphism in
record.field.subfield
(It's the same as theshow(read(x))
problem: read convertsx
from aString
;show
turns a value into aString
; but type inference can't guess the type of the value in the middle, so doesn't know how toshow
it.)So early Haskell probably was wise to be timid. The power of type inference has come a long way since 1995. Records not.
Quote from tobega on July 10, 2025, 2:18 pm..., I suppose everything would have worked out neatly by ad-hoc polymorphism on the accessor functions.
Hehe, bless you. The field (content) might have polymorphic type -- indeed might itself be a nested record. So there was a ~2015 proposal from a top honcho that got banjaxed/defeated by too much polymorphism in record.field.subfield
(It's the same as the show(read(x))
problem: read converts x
from a String
; show
turns a value into a String
; but type inference can't guess the type of the value in the middle, so doesn't know how to show
it.)
So early Haskell probably was wise to be timid. The power of type inference has come a long way since 1995. Records not.
Quote from AntC on July 11, 2025, 6:09 amQuote from Darren Duncan on July 11, 2025, 12:29 am... Java and C# is that its base syntax is much smaller, and mostly based on English words with few symbols, ...
Part of the difficulty with addressing Haskell's
.
is that the language reserves so few symbols. This was to allow you to define your own family of operators. (So another bit of backward incompatibility is that any glyph Haskell tries to reserve for some of the purposes of.
is probably in use as an operator in some distant galaxy; there'll be howls of outrage.)Some Haskellers have taken this minimalism as an invitation to define vast hordes of operators, so it's perfectly possible for Haskell to resemble line noise. Operators can be a sequence of non-alphas -- which seems reasonable for
&&
(Boolean And),||
(Or). Single&
isflip ($)
, obviously. Monad operators>>=
,>>
are supposed to suggest some sort of feeding results through computations. There's a whole cottage industry forLens
es:^.
,^?
,^?!
,.~
,%~
, which are so intuitive, they barely need documenting.
Quote from Darren Duncan on July 11, 2025, 12:29 am... Java and C# is that its base syntax is much smaller, and mostly based on English words with few symbols, ...
Part of the difficulty with addressing Haskell's .
is that the language reserves so few symbols. This was to allow you to define your own family of operators. (So another bit of backward incompatibility is that any glyph Haskell tries to reserve for some of the purposes of .
is probably in use as an operator in some distant galaxy; there'll be howls of outrage.)
Some Haskellers have taken this minimalism as an invitation to define vast hordes of operators, so it's perfectly possible for Haskell to resemble line noise. Operators can be a sequence of non-alphas -- which seems reasonable for &&
(Boolean And), ||
(Or). Single &
is flip ($)
, obviously. Monad operators >>=
, >>
are supposed to suggest some sort of feeding results through computations. There's a whole cottage industry for Lens
es: ^.
, ^?
, ^?!
, .~
, %~
, which are so intuitive, they barely need documenting.
Quote from Darren Duncan on July 11, 2025, 7:09 amQuote from AntC on July 11, 2025, 6:09 amQuote from Darren Duncan on July 11, 2025, 12:29 am... Java and C# is that its base syntax is much smaller, and mostly based on English words with few symbols, ...
Part of the difficulty with addressing Haskell's
.
is that the language reserves so few symbols. This was to allow you to define your own family of operators. (So another bit of backward incompatibility is that any glyph Haskell tries to reserve for some of the purposes of.
is probably in use as an operator in some distant galaxy; there'll be howls of outrage.)Some Haskellers have taken this minimalism as an invitation to define vast hordes of operators, so it's perfectly possible for Haskell to resemble line noise. Operators can be a sequence of non-alphas -- which seems reasonable for
&&
(Boolean And),||
(Or). Single&
isflip ($)
, obviously. Monad operators>>=
,>>
are supposed to suggest some sort of feeding results through computations. There's a whole cottage industry forLens
es:^.
,^?
,^?!
,.~
,%~
, which are so intuitive, they barely need documenting.Further to my point, it's not just the base syntax size, but what users can define. In Java and C#, users can't define new symbolic operators either, just alphanumeric named entities, so the language is entirely English-like words with only a dozen or two language-defined symbolics.
What you describe about Haskell also reminds me of the Raku (nee Perl 6) language, which DOES allow users to define symbolic operators, and new syntax in general, and has a huge number system-defined, so Raku code can be quite syntactically dense if users want it to be.
Note that Haskell was also the programming language that Raku's first serious implementation was in, around 2005-2006, and the means by which some of its more innovative new features such as Junctions (like non-collapsed wave functions of quantum physics) were first proven with working implementations.
Quote from AntC on July 11, 2025, 6:09 amQuote from Darren Duncan on July 11, 2025, 12:29 am... Java and C# is that its base syntax is much smaller, and mostly based on English words with few symbols, ...
Part of the difficulty with addressing Haskell's
.
is that the language reserves so few symbols. This was to allow you to define your own family of operators. (So another bit of backward incompatibility is that any glyph Haskell tries to reserve for some of the purposes of.
is probably in use as an operator in some distant galaxy; there'll be howls of outrage.)Some Haskellers have taken this minimalism as an invitation to define vast hordes of operators, so it's perfectly possible for Haskell to resemble line noise. Operators can be a sequence of non-alphas -- which seems reasonable for
&&
(Boolean And),||
(Or). Single&
isflip ($)
, obviously. Monad operators>>=
,>>
are supposed to suggest some sort of feeding results through computations. There's a whole cottage industry forLens
es:^.
,^?
,^?!
,.~
,%~
, which are so intuitive, they barely need documenting.
Further to my point, it's not just the base syntax size, but what users can define. In Java and C#, users can't define new symbolic operators either, just alphanumeric named entities, so the language is entirely English-like words with only a dozen or two language-defined symbolics.
What you describe about Haskell also reminds me of the Raku (nee Perl 6) language, which DOES allow users to define symbolic operators, and new syntax in general, and has a huge number system-defined, so Raku code can be quite syntactically dense if users want it to be.
Note that Haskell was also the programming language that Raku's first serious implementation was in, around 2005-2006, and the means by which some of its more innovative new features such as Junctions (like non-collapsed wave functions of quantum physics) were first proven with working implementations.
Quote from Dave Voorhis on July 12, 2025, 8:26 pmQuote from tobega on July 10, 2025, 2:18 pmI always loved programming in Java (still do), but you get looked at strangely these days if you admit it.
I freely admit loving programming in Java, and if anyone emits strange looks I automatically deduct ten points from their worth as programming commentators.
Java plays a very significant role in the industry and if you deprecate that I question your maturity -- in spite of Java's flaws. But Java has the distinction of being consistently more mediocre than any other language at almost everything except embedded systems and low-level systems programming (and maybe videogames), which makes it more tolerably suitable than any other language for almost everything except embedded systems and low-level systems programming (and maybe videogames.)
It's gotten even better with records and pattern-matching.
A lot of Java criticisms come from those who haven't looked at Java -- or at least good Java code -- since before Java 8 (where it changed significantly), and sometimes before Java 2. The current version is Java 24.
I exaggerated the "line noise". What they showed was that a beginner could understand any randomly generated symbol almost as well as the symbols chosen for Java syntax. The readability in Java programs comes from naming, anyway.
A lot comes from enterprise Java development, where it's typical for teams of developers to descend on a legacy project without having seen it before, are expected to make major changes to functionality in a short period of time, and must put the result online and earning/managing/whatevering business critical whatnots as soon as possible. No time or patience for deciphering whether the '-' in some expression is really numeric subtraction or some overriding of that symbol.
Whilst I'm here, I grit my teeth at the Pythonistas who argue Python would be as good if not better for enterprise development, but obviously have never had to decipher what valid types can be passed to or returned by a function like
spfrbpl(dflt, fvf, tree)
. No time or patience for that.And then there's C#, which is like a slightly better Java (*cough* Kotlin *cough*) but the 3rd party libraries, unlike the high-quality offerings for the Java ecosystem with professional developers and corporate sponsorship, tend to be undocumented student projects or equivalent or worse quality.
Quote from tobega on July 10, 2025, 2:18 pmI always loved programming in Java (still do), but you get looked at strangely these days if you admit it.
I freely admit loving programming in Java, and if anyone emits strange looks I automatically deduct ten points from their worth as programming commentators.
Java plays a very significant role in the industry and if you deprecate that I question your maturity -- in spite of Java's flaws. But Java has the distinction of being consistently more mediocre than any other language at almost everything except embedded systems and low-level systems programming (and maybe videogames), which makes it more tolerably suitable than any other language for almost everything except embedded systems and low-level systems programming (and maybe videogames.)
It's gotten even better with records and pattern-matching.
A lot of Java criticisms come from those who haven't looked at Java -- or at least good Java code -- since before Java 8 (where it changed significantly), and sometimes before Java 2. The current version is Java 24.
I exaggerated the "line noise". What they showed was that a beginner could understand any randomly generated symbol almost as well as the symbols chosen for Java syntax. The readability in Java programs comes from naming, anyway.
A lot comes from enterprise Java development, where it's typical for teams of developers to descend on a legacy project without having seen it before, are expected to make major changes to functionality in a short period of time, and must put the result online and earning/managing/whatevering business critical whatnots as soon as possible. No time or patience for deciphering whether the '-' in some expression is really numeric subtraction or some overriding of that symbol.
Whilst I'm here, I grit my teeth at the Pythonistas who argue Python would be as good if not better for enterprise development, but obviously have never had to decipher what valid types can be passed to or returned by a function like spfrbpl(dflt, fvf, tree)
. No time or patience for that.
And then there's C#, which is like a slightly better Java (*cough* Kotlin *cough*) but the 3rd party libraries, unlike the high-quality offerings for the Java ecosystem with professional developers and corporate sponsorship, tend to be undocumented student projects or equivalent or worse quality.
Quote from Darren Duncan on July 12, 2025, 9:25 pmQuote from Dave Voorhis on July 12, 2025, 8:26 pmQuote from tobega on July 10, 2025, 2:18 pmI always loved programming in Java (still do), but you get looked at strangely these days if you admit it.
I freely admit loving programming in Java, and if anyone emits strange looks I automatically deduct ten points from their worth as programming commentators.
Java plays a very significant role in the industry and if you deprecate that I question your maturity -- in spite of Java's flaws. But Java has the distinction of being consistently more mediocre than any other language at almost everything except embedded systems and low-level systems programming (and maybe videogames), which makes it more tolerably suitable than any other language for almost everything except embedded systems and low-level systems programming (and maybe videogames.)
I agree with Dave.
I go further and say I feel Java is actually the best programming language to reach for by default for any application programming task unless there is a specific use-case justification that some other language would be better.
I also question the assertion that Java is consistently more mediocre at other domains. For example, I would reach for it any day of the week to write a web application over the likes of Python or PHP or Go or Node or whatever. (I would also use TypeScript, but only for a front-end running inside a web client.)
Quote from Dave Voorhis on July 12, 2025, 8:26 pmQuote from tobega on July 10, 2025, 2:18 pmI always loved programming in Java (still do), but you get looked at strangely these days if you admit it.
I freely admit loving programming in Java, and if anyone emits strange looks I automatically deduct ten points from their worth as programming commentators.
Java plays a very significant role in the industry and if you deprecate that I question your maturity -- in spite of Java's flaws. But Java has the distinction of being consistently more mediocre than any other language at almost everything except embedded systems and low-level systems programming (and maybe videogames), which makes it more tolerably suitable than any other language for almost everything except embedded systems and low-level systems programming (and maybe videogames.)
I agree with Dave.
I go further and say I feel Java is actually the best programming language to reach for by default for any application programming task unless there is a specific use-case justification that some other language would be better.
I also question the assertion that Java is consistently more mediocre at other domains. For example, I would reach for it any day of the week to write a web application over the likes of Python or PHP or Go or Node or whatever. (I would also use TypeScript, but only for a front-end running inside a web client.)
Quote from Dave Voorhis on July 12, 2025, 10:25 pmQuote from Darren Duncan on July 12, 2025, 9:25 pmI also question the assertion that Java is consistently more mediocre at other domains. For example, I would reach for it any day of the week to write a web application over the likes of Python or PHP or Go or Node or whatever. (I would also use TypeScript, but only for a front-end running inside a web client.)
What I meant by "consistently more mediocre than any other language" was a tongue-in-cheek way of suggesting that it makes all the right compromises.
PHP, for example, may be better than Java in some ways but is utterly dire in others. The same applies to Go, TypeScript, Python, C#, Haskell, you-name-it. Whilst Java lacks the occasional greatnesses found in all of these, it also lacks their occasional (and occasionally pervasive) nasties.
In short, Java doesn't soar as high, but also doesn't dip as low. That makes it, in most cases, a better choice where you might be inclined to choose something else.
Quote from Darren Duncan on July 12, 2025, 9:25 pmI also question the assertion that Java is consistently more mediocre at other domains. For example, I would reach for it any day of the week to write a web application over the likes of Python or PHP or Go or Node or whatever. (I would also use TypeScript, but only for a front-end running inside a web client.)
What I meant by "consistently more mediocre than any other language" was a tongue-in-cheek way of suggesting that it makes all the right compromises.
PHP, for example, may be better than Java in some ways but is utterly dire in others. The same applies to Go, TypeScript, Python, C#, Haskell, you-name-it. Whilst Java lacks the occasional greatnesses found in all of these, it also lacks their occasional (and occasionally pervasive) nasties.
In short, Java doesn't soar as high, but also doesn't dip as low. That makes it, in most cases, a better choice where you might be inclined to choose something else.
Quote from dandl on July 13, 2025, 12:53 amI agree, Dave. Java is the best available GP/enterprise/big app language for most use cases. I prefer C# for its genuine value types and generics, but the gap has been narrowing. Java is unusable (and unused) for any kind of games development, where Unity/C# are big. There are also Microsoft niche areas where C# wins. But the lack of broad infrastructure libraries is ultimately the killer.
But either way strict typing IMO is critical for large maintainable codebases.
Python is lovely for the first 300 lines, tolerable up to 3000, awful beyond that. PHP and anything JS-ish are effectively web-only. C++ wins for really low level stuff, hopefully put in a library and called from Java/C#, although it does have valid competitors (eg Rust). Most everything else is line noise.
I agree, Dave. Java is the best available GP/enterprise/big app language for most use cases. I prefer C# for its genuine value types and generics, but the gap has been narrowing. Java is unusable (and unused) for any kind of games development, where Unity/C# are big. There are also Microsoft niche areas where C# wins. But the lack of broad infrastructure libraries is ultimately the killer.
But either way strict typing IMO is critical for large maintainable codebases.
Python is lovely for the first 300 lines, tolerable up to 3000, awful beyond that. PHP and anything JS-ish are effectively web-only. C++ wins for really low level stuff, hopefully put in a library and called from Java/C#, although it does have valid competitors (eg Rust). Most everything else is line noise.