From anthony_clayden at clear.net.nz Sat May 2 12:15:44 2020 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Sun, 3 May 2020 00:15:44 +1200 Subject: [Hugs-users] fun with yacc, and with Trex Message-ID: To keep the Hugs community in the loop ... Now that I have a compilable compiler, I'm picking some low-hanging fruit with syntax sugar. * I've taught Trex to support field labels starting upper-case, because, well for me they're more like constructors than variables. Unlike H98, Trex doesn't generate field accessor functions. You get #label -- or rather #Label for that. * I've always wanted records to use syntax with braces { X = 1, Y = 2 } , because, well they're a set of name-value pairs, not a mathematician's sequenced tuple. Indeed the original Gaster & Jones 1996 paper used braces. * A slight compromise: the syntax just above is ambiguous with H98, so you must put a | at the end { X = 1, Y = 2 |}. yacc inserts a `emptyRec` in the end. * And I have a format for building or updating records that uses straight { } rather than suffixing it. Might as well propose it for GHC https://github.com/ghc-proposals/ghc-proposals/issues/328. So H98 syntax, my better syntax and Trex with { ... } are co-existing. * I've added a form of NamedFieldPuns for Trex -- in both expressions and patterns: foo { X = | r } = { Y = ##X, X = | r } Heh heh punning on upper-case field labels gives an upper-case variable name. ##X goes grab the pseudo-variable. * And that's all achieved with yacc (and a bit of lexing). I haven't touched the main compiler code, which gives me good confidence I didn't stuff something up. I'm now looking at stealing some syntax from the Habit language. And syntax for FunDeps more in line with the original Mark Jones 2000 paper. Because in class C a b c | a b -> c where ... `a b` does not mean `a` applied to `b`. Also that arrow is misleading: there's not a function, but a mechanism for unification/type improvement, which is chiefly aimed at improving `c`, but might also improve `{a, b}` at some usage sites. (The original paper used `~>`, in which the tilde nicely echoes GHC's so called 'type equality constraint' -- again that's a two-way unification mechanism, not merely a type-level test.) AntC -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony_clayden at clear.net.nz Wed May 6 10:37:51 2020 From: anthony_clayden at clear.net.nz (Anthony Clayden) Date: Wed, 6 May 2020 22:37:51 +1200 Subject: [Hugs-users] Some idioms for Trex Message-ID: Making best use of Trex needs a different mindset vs H98 datatypes with named fields. (Or indeed vs named-fields data structures in many languages) There's some examples around in the Trex/Hugs material, but I've seen nothing showing this: > type WPoint r = (x :: Float, y :: Float | r) -- r extended "with Point" > type WRadius r = (radius :: Float | r) > type WColour r = (colour :: String | r) > type ColouredCircle = Rec( WColour (WRadius (WPoint EmptyRow))) The idea is rather than nest 'Point' as a datatype inside 'Circle' 'plug and play' components (such as Point, Radius) to give a structural type. It's interesting and impressive that the Wxxx synonyms take an argument of kind row, return a result of kind row. `EmptyRow` in the last line is a Hugs-defined Row constant that 'plugs' the end of the composed components, just as `emptyRec` does for Trex Records. I'd love to write that last type as > type MkRec r = Rec( r EmptyRow) > type ColouredCircle = MkRec (WColour . WRadius . WPoint) But of course type synonyms -- even with parameters -- are not functions; can't be composed; can't be passed to higher-order type synonyms. Components like WPoint can be arguments to type-parametric functions for record subtyping: such as a generic routine to 'move' any shape by modifying its x, y coordinates. 'Move' in scare quotes because that's returning a copy of the shape's data structure with modified coordinates, not poking values into an object/reference. -------------- next part -------------- An HTML attachment was scrubbed... URL: