Re: [Haskell-cafe] Prolog-style list syntax?

`[ x, y, z | zs ]` is also valid; [...] That structure is particularly ugly in Haskell syntax.
how so? `x : y : z : zs` Prolog list syntax is ugly here because the "cons" operator (|) needs special parentheses. Well, a similar thing in Haskell ist the ".." (enumFromTo) operator. For syntactic generality, you could go full Agda https://agda.readthedocs.io/en/v2.6.0.1/language/mixfix-operators.html but I'm not sure whether brackets could be "name parts" - J.W.

I did some work with Erlang, which uses Prolog-style syntax. I've always found this [H|T] to be confusing, since T is not an element of that list. But it could be because I've learned Haskell before Erlang.
On 28 Jun 2021, at 13:09, Johannes Waldmann
wrote: `[ x, y, z | zs ]` is also valid; [...] That structure is particularly ugly in Haskell syntax.
how so? `x : y : z : zs`
Prolog list syntax is ugly here because the "cons" operator (|) needs special parentheses.
Well, a similar thing in Haskell ist the ".." (enumFromTo) operator.
For syntactic generality, you could go full Agda https://agda.readthedocs.io/en/v2.6.0.1/language/mixfix-operators.html but I'm not sure whether brackets could be "name parts"
- J.W. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Having learned Erlang before Haskell, I recall having the opposite opinion at first. ;) Le 28/06/2021 à 13:26, MigMit a écrit :
I did some work with Erlang, which uses Prolog-style syntax. I've always found this [H|T] to be confusing, since T is not an element of that list. But it could be because I've learned Haskell before Erlang.
On 28 Jun 2021, at 13:09, Johannes Waldmann
wrote: `[ x, y, z | zs ]` is also valid; [...] That structure is particularly ugly in Haskell syntax. how so? `x : y : z : zs`
Prolog list syntax is ugly here because the "cons" operator (|) needs special parentheses.
Well, a similar thing in Haskell ist the ".." (enumFromTo) operator.
For syntactic generality, you could go full Agda https://agda.readthedocs.io/en/v2.6.0.1/language/mixfix-operators.html but I'm not sure whether brackets could be "name parts"
- J.W. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- Hécate ✨ 🐦: @TechnoEmpress IRC: Hecate WWW: https://glitchbra.in RUN: BSD

On Jun 28, 2021, at 4:09 AM, Johannes Waldmann
`[ x, y, z | zs ]` is also valid; [...] That structure is particularly ugly in Haskell syntax.
how so? `x : y : z : zs`
I don’t mind the existing either, but it would be interesting if this worked: [x, y, z] ++ zs = list But really, it redefines (++), so it has a different meaning already. But you could imagine some special syntax “outside” the brackets, instead of inside. Jeff

On Mon, Jun 28, 2021 at 11:04:46AM -0700, Jeff Clites via Haskell-Cafe wrote:
how so? `x : y : z : zs`
I don’t mind the existing either, but it would be interesting if this worked:
[x, y, z] ++ zs = list
It is far from clear why this or any similar pattern would be more ergonomic than: x : y : z : zs -- Viktor.

I have definitely wanted this for strings: "prefix" ++ xs = string Is much better than: 'p' : 'r' : 'e' : 'f' : 'i' : 'x' : xs = string Jaro On 28-06-2021 20:15, Viktor Dukhovni wrote:
On Mon, Jun 28, 2021 at 11:04:46AM -0700, Jeff Clites via Haskell-Cafe wrote:
how so? `x : y : z : zs`
I don’t mind the existing either, but it would be interesting if this worked:
[x, y, z] ++ zs = list
It is far from clear why this or any similar pattern would be more ergonomic than:
x : y : z : zs
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Me too, but is it really worth breaking language consistency for something that can be done as a library? Just xs = stripPrefix "prefix" On Mon, Jun 28, 2021 at 08:22:00PM +0200, Jaro Reinders wrote:
I have definitely wanted this for strings:
"prefix" ++ xs = string
Is much better than:
'p' : 'r' : 'e' : 'f' : 'i' : 'x' : xs = string
On 28-06-2021 20:15, Viktor Dukhovni wrote:
On Mon, Jun 28, 2021 at 11:04:46AM -0700, Jeff Clites via Haskell-Cafe wrote:
how so? `x : y : z : zs`
I don’t mind the existing either, but it would be interesting if this worked:
[x, y, z] ++ zs = list
It is far from clear why this or any similar pattern would be more ergonomic than:
x : y : z : zs

On Jun 28, 2021, at 11:15 AM, Viktor Dukhovni
wrote: On Mon, Jun 28, 2021 at 11:04:46AM -0700, Jeff Clites via Haskell-Cafe wrote:
how so? `x : y : z : zs`
I don’t mind the existing either, but it would be interesting if this worked:
[x, y, z] ++ zs = list
It is far from clear why this or any similar pattern would be more ergonomic than:
x : y : z : zs
The thread started with:
One of the annoying (to me) inconsistencies with Haskell syntax is that `[ ]` means 'here comes a list'; but for the most common way to write a list, you can't use `[ ]`:
elem x [] = False elem x ( y: ys ) = ...
I sympathize with that observation, that there’s a special syntax for constructing lists, but you can’t use a similar syntax for the most common pattern-matching case (you can only use it for matching all elements of the list), and the special syntax is a nice visual signal that you are working with lists. It’s not that x : y : z : zs is bad, it’s just not as distinctive. Someone thought it was worth inventing [a, b, c] even though you could just have written a : b : c : Nil, so similar motivations apply. Something like this might work: [x, y, z, zs*] = list But I actually like this the best: [x, y, z, zs...] = list (The overlap with existing range syntax might actually be beneficial.) Jeff

On Mon, Jun 28, 2021 at 10:57:16PM -0700, Jeff Clites via Haskell-Cafe wrote:
Something like this might work:
[x, y, z, zs*] = list
But it could be that "*" in this context is defined as a postfix unary operator, and "zs*" is just another element.
But I actually like this the best:
[x, y, z, zs...] = list
Same here with "...". Neither "*" nor "..." is built in to Haskell as a reserved operator. -- Viktor.

On Mon, 28 Jun 2021 at 23:20, Johannes Waldmann < johannes.waldmann@htwk-leipzig.de> wrote:
`[ x, y, z | zs ]` is also valid; [...] That structure is particularly ugly in Haskell syntax.
how so? `x : y : z : zs`
Because almost always you need to put parens round -- certainly in a pattern match. And it's not square brackets, which would say 'here comes a list'.
Prolog list syntax is ugly here because the "cons" operator (|) needs special parentheses.
Exactly! Special list-heralding brackets.
Well, a similar thing in Haskell ist the ".." (enumFromTo) operator.
@Jeff But I actually like this the best:
[x, y, z, zs...] = list
Or maybe
[x, y, z, zs@..] = list
Could be an as-pattern binding to the tail. But now it's getting heavyweight.

On Tue, Jun 29, 2021 at 7:05 AM Anthony Clayden
Because almost always you need to put parens round -- certainly in a pattern match.
This is an interesting point, and for the sake of having an unambiguous parser, I don't think this requirement is needed: The arity of all constructors is known, all constructors must have all of its arguments (no currying in patterns), so Polish notation should suffice and parentheses could be optional (an implementer would need to delay parsing of anything to the lhs of an <- or = until all constructors are known). With infix operators (`a:b:c` should not be parsed as `(a:b):c`) we simply take fixity into. To a certain extent Haskell already does this, the following works: infixr 3 `member` a `member` [] = False a `member` b : bs | b==a = True | otherwise = a `member` bs To make this work in general, any function symbols on the lhs of an = (and their respective function application) should have the lowest precedence, and constructor 'application' through spaces would seem to go in the opposite direction of what is common. Following this convention, we could have this amusing looking definition in the Prelude: x:xs++ys = x:xs++ys On the lhs, since ++ is not a constructor, it is the symbol that is being defined and therefore of lowest precedence, so the lhs would read (x:xs)++ys. On the rhs, (:) and (++) are infixr 5, so the rhs reads as x:(xs++ys). Just to be clear: none of this is a proposal, I would not be in favor of this as I prefer consistency. As to the original question: I see no technical issues in allowing something like `[ x, y || ys]` as syntax for `(x:y:ys)`, or using any new symbol in place of ||. As others have pointed out, we cannot have all three of: - `[ expr ]` stands for singleton list elements (as currently the case) - keep the current meaning of `x : xs` - let `[ x : xs ]` be 'shorthand' for `x:xs`
From a Prolog perspective, dropping `x : xs` may seem the way to go (arguments like: "in many patterns we need parentheses anyways" seem to agree with this view), but Haskell code has `foo x y` instead of `foo(x,y)`, and infix syntax follows the same principle: outer parentheses are optional. Prolog follows the same principle for +, *, -, =, etc, just not for relations.
Would I be violently against even something mild like the introduction of `[ x,y || ys ]`? Not violently so but definitely fiercely, unless this is tucked away behind a flag. I see it as pointless, wouldn't use it, and I don't care to explain it to my students (or at least those who don't know Prolog) either, and it would reduce 3rd party code readability because there would now be two ways of writing the same thing, neither of which is entirely obvious. In a new / different language I'd love to see all these weird ideas tried out. Sometimes odd conventions (such as writing `foo x y` instead of `foo(x,y)`) grow on me and I start to like them. A good place to start might be to add outer parentheses to your language to distinguish `[x : xs]` from `[(x : xs)]`, forbidding `x : xs`. This would be LISP with infix notations and static typing... that actually sounds like it could be nice. While we're on the topic of changing list syntax, some more ideas that might make sense (but are not a proposal!!): `[ x,y | binders ]` as syntax for: `concat [ [x,y] | binders ]` `[ x ..< y ]` as syntax for `FromEnumToExclusive x y` (i.e. `if x==y then [] else [x..pred y]` by default), Isabelle/HOL has this. A keyword `get` in addition to `let` s.t. `[x | get Just x = y]` is syntax for `[x | Just x <- [y]]` (using let produces a pattern match failure if y=Nothing). While we're at it: `do {get Just x = ys; continuation}` as syntax for `do {Just x <- return ys; continuation}`. `[ x | xs <- as; x <- xs]` as syntax for: `[x | xs <- as, x <- xs]` (the ; would have the binders behave like `do-syntax`). While we're at it: `[ expr | binders]` as syntax for: `do {binders;return expr} :: (Listlike f => f b)` with `default Listlike ([])`. Finally, `do {(binders1 | binders2) ; continuation}` could be syntax for: `Data.Zip.zipWith (\x y -> continuation) (do binders1;return x) (do binders2; return y)` (as inspired by parallel list comprehensions). It's fun to think about these things, but each of these ideas comes with syntactic change and therefore yet another language construct to learn. Since syntax cannot be found on hoogle https://hoogle.haskell.org/?hoogle=.. and even google <http://what does .. mean in haskell>, all of these things generally increase the burden to the reader of your code, which is why none of this is a proposal. Best, Sebastiaan
participants (9)
-
Anthony Clayden
-
Hécate
-
Jaro Reinders
-
Jeff Clites
-
Johannes Waldmann
-
MigMit
-
Sebastiaan Joosten
-
Tom Ellis
-
Viktor Dukhovni