[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