Prolog-style list syntax?

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 ) = ...
Prolog syntax has lists, signalled by `[ ]`: [], [1], [2, 3], [4, 5, 6], [[7, 8], [9, 10, 11]] are all valid list literals. For cons it also uses `[ ]` syntax
elem x [y | ys ] = ...
`[ x, y, z | zs ]` is also valid; pattern match or build a list with at least 3 elements, where `zs` is the tail -- 4th element onwards (if any). That structure is particularly ugly in Haskell syntax. Neither `|` inside `[ ]` in a pattern nor a comma-list with `|` inside `[ ]` is valid H98 syntax, nor valid in GHC extensions AFAICT. In an expression, `[ x | xs ]` could be taken as a list comprehension, which is I guess why Haskell didn't follow Prolog. I've come across another theorem-prover that follows Prolog style, except it uses `:` instead of `|` inside `[ ]`. Unfortunately ...
elem x [ y: ys ] = ...
Is valid syntax, where `:` is cons, so this is a nested list. I'm thinking that's relatively uncommon, and means the same as `[ ( y: ys ) ]`. Would anyone be violently pro or anti changing the meaning of `:` appearing at top level in `[ ]` to mean cons-tail? AntC

I'd definitely be against what you propose; as you pointed out it
introduces a syntax ambiguity, which I think should be avoided where
possible.
On Mon, 28 Jun 2021, 4:19 pm Anthony Clayden,
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 ) = ...
Prolog syntax has lists, signalled by `[ ]`: [], [1], [2, 3], [4, 5, 6], [[7, 8], [9, 10, 11]] are all valid list literals. For cons it also uses `[ ]` syntax
elem x [y | ys ] = ...
`[ x, y, z | zs ]` is also valid; pattern match or build a list with at least 3 elements, where `zs` is the tail -- 4th element onwards (if any). That structure is particularly ugly in Haskell syntax.
Neither `|` inside `[ ]` in a pattern nor a comma-list with `|` inside `[ ]` is valid H98 syntax, nor valid in GHC extensions AFAICT.
In an expression, `[ x | xs ]` could be taken as a list comprehension, which is I guess why Haskell didn't follow Prolog. I've come across another theorem-prover that follows Prolog style, except it uses `:` instead of `|` inside `[ ]`. Unfortunately ...
elem x [ y: ys ] = ...
Is valid syntax, where `:` is cons, so this is a nested list. I'm thinking that's relatively uncommon, and means the same as `[ ( y: ys ) ]`.
Would anyone be violently pro or anti changing the meaning of `:` appearing at top level in `[ ]` to mean cons-tail?
AntC _______________________________________________ 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.

On 2021-06-28 2:17 a.m., Anthony Clayden wrote:
Prolog syntax has lists, signalled by `[ ]`: [], [1], [2, 3], [4, 5, 6], [[7, 8], [9, 10, 11]] are all valid list literals. For cons it also uses `[ ]` syntax
elem x [y | ys ] = ...
`[ x, y, z | zs ]` is also valid; pattern match or build a list with at least 3 elements, where `zs` is the tail -- 4th element onwards (if any). That structure is particularly ugly in Haskell syntax.
Prolog list syntax is the annoying one to me because it is watered down Hungarian notation again but with symbols instead of letters. "If it's a string, prefix with sz; if it's a list, surround with []". The logical conclusion of "elem : list" is e1 : e2 : e3 : e4 : list without needing a 2nd notation to make it nicer. The logical conclusion of "[elem | list]" is [e1 | [e2 | [e3 | [e4 | list]]]] That's not nice. That explains why someone had to invent a 2nd notation, [e1, e2, e3, e4 | list]. Ironically, the need for a 2nd notation proves that the original "[elem | list]" design was ill-conceived.

On Tue, 29 Jun 2021 at 04:07, Albert Y. C. Lai
The logical conclusion of "elem : list" is
e1 : e2 : e3 : e4 : list
without needing a 2nd notation to make it nicer.
(As I said up-thread you almost always need to add the parens notation -- not to make it "nicer", but to make it parse correctly.) I appreciate syntax is a matter of personal taste, but my taste prefers the brackets and commas.
The logical conclusion of "[elem | list]" is
[e1 | [e2 | [e3 | [e4 | list]]]]
That's not nice.
Quite often `e1:e2:e3:e4:list` won't work, because the expressions have infix operators. So you end up with
(e1: (e2: (e3: (e4: list))))
So you still have to squint to make sure the parens balance.
That explains why someone had to invent a 2nd notation, [e1, e2, e3, e4 | list].
Sure. The commas form is a shorthand. Just like
(e1, e2, e3, e4) is shorthand for (,,,) e1 e2 e3 e4 e1 + e2 * e3 is shorthand for (+) e1 ((*) e2 e3)
Ironically, the need for a 2nd notation proves that the original "[elem | list]" design was ill-conceived.
So which form of tuple syntax do you think is ill-conceived?

On Mon, Jun 28, 2021 at 06:17:42PM +1200, Anthony Clayden wrote:
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 ) = ...
Yes, there's presently no way to pattern-match a list tail inside `[]`.
Unfortunately ...
elem x [ y: ys ] = ...
Is valid syntax, where `:` is cons, so this is a nested list. I'm thinking that's relatively uncommon, and means the same as `[ ( y: ys ) ]`.
Would anyone be violently pro or anti changing the meaning of `:` appearing at top level in `[ ]` to mean cons-tail?
I'm on the violently against side on the question of `[x : ys]` being reinterpreted as `(x : ys)`. For any expression `e1, we have a singleton `[e]`, and there should not be any surprising exceptions to that rule. If something new is to pattern match as `x : ys` inside `[]` it would have to be invalid syntax presently. So it could in principle be: [x,,ys] but I'm concerned that this is too likely to be an inadvertent typo, as in: [ x, , y ] It is probably more useful to catch this sort of error, than to overload the syntax for head + tail pattern matches. So on the whole, I'm inclined to accept the status quo. The annoyance, if any, of having to use `(x : ys)` in pattern matches would not be solved by adding a third syntax for lists. -- Viktor.
participants (4)
-
Albert Y. C. Lai
-
Anthony Clayden
-
Isaac Elliott
-
Viktor Dukhovni