[m-users.] Concise syntax for initialising and updating discriminated union types
Volker Wysk
post at volker-wysk.de
Tue Jul 19 03:04:34 AEST 2022
Am Montag, dem 18.07.2022 um 17:55 +0100 schrieb Sean Charles
(emacstheviking):
> I too have had similar thoughts, but in the end I settle for what already exists.
>
> For any DU type I have a 'default' constructor function e.g. this one from my literate programming tool :-
>
> :- func pstate_init(string::in) = (pstate::out) is det.
>
> pstate_init(Filename) = pstate(
> Filename, % For errors
> skip_text, % Initial parse state
> 0, % Pandoc size open/close filter
> plain_text(-1, ""), % Last fence header seen
> no, % Current block name scanned
> no, % Last block name scanned
> map.init : codeblock_map, % Named blocks collection
> [], % current block content
> [] % Error messages
> ).
>
> If I find myself updating two or three fields one after the other more
> than once then I just abstract it away into a predicate so it's following
> DRY, and if one is really concerned with performance then you can 'inline'
> it by I don't go that far.
What does "DRY" mean?
> TBH I quite like the way Mercury --insists-- that I do things by the book,
> there is a stark unyielding beauty to the way it makes you write your code
> in certain ways, and coupled with the fact I never go over column 79, it
> reminds my of the good old days of a VT220!
>
>
>
>
> > On 18 Jul 2022, at 17:50, Volker Wysk <post at volker-wysk.de> wrote:
> >
> > Hi!
> >
> > There are two things which occur to me every now and then, about working
> > with discriminated union types with field names.
> >
> > 1. How to initialise a value of a discriminated union type, by using field
> > names (similar to the way they can be used for field access and field update
> > functions)?
> >
> > I find myself defining a "null" value, which is initialised without usage of
> > field names. But this is error prone. Afters, I change fields of that null
> > value to get my value.
> >
> > This leads to point no. 2:
> >
> > 2. How to concisely update multiple fields? You can do this in multiple
> > steps, like this:
> >
> > konstr1(LP3) :-
> > LP1 = 'lp_link_target :='(null_link_parts, "Target"),
> > LP2 = 'lp_link_subsection :='(LP1, yes("Subs.")),
> > LP3 = 'lp_link_text :='(LP2, "bla").
> >
> > But this too, is rather verbose and maybe error prone.
> >
> > The code smells very much like state variables. It could be done like this:
> >
> > konstr3(Out) :-
> > some [!LP] (
> > !:LP = null_link_parts,
> > lp_link_target("Target", !LP),
> > lp_link_subsection(yes("Subs."), !LP),
> > lp_link_text("bla", !LP),
> > Out = !.LP
> > ).
> >
> > For this, there need to be defined field update predicates:
> >
> > lp_link_target(Val, In, Out) :- Out = 'lp_link_target :='(In, Val).
> > lp_link_subsection(Val, In, Out) :- Out = 'lp_link_subsection :='(In, Val).
> > lp_link_text(Val, In, Out) :- Out = 'lp_link_text :='(In, Val).
> >
> >
> > So there are two things that I'm missing.
> >
> > 1. A concise syntax for initialising values of a discriminated union type.
> > Something like this (link_parts is a data constructor):
> >
> > link_parts(lp_link_target = "Target",
> > lp_link_subsection = yes("Subs."),
> > lp_link_text = "bla").
> >
> > The compiler would complain when some fields aren't initialised.
> >
> > 2. Some concise way to update multiple fields, like above. Maybe the
> > compiler could additionally generate field update predicates for the fields
> > (like above), similar to field update functions.
> >
> >
> > Cheers,
> > Volker
> > _______________________________________________
> > users mailing list
> > users at lists.mercurylang.org
> > https://lists.mercurylang.org/listinfo/users
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.mercurylang.org/archives/users/attachments/20220718/6719a08a/attachment.sig>
More information about the users
mailing list