Here is a linear version:

https://pastebin.com/sqXcRhnf

Also, Command is a linear datatype (i.e., dataviewtype).


On Tue, Mar 26, 2019 at 9:02 AM Hongwei Xi <gmh...@gmail.com> wrote:

> Nice!
>
> But I am very surprised that this code actually works.
> My understanding is that It works because of a bug in patsopt :)
>
> Basically, runCommand should be implemented as a polymorphic function
> (instead of a function
> template). And 'a:t0ype' should be 'a:type'.
>
> fun runCommand: {a:type} Command(a) -> a
>
> Actually, I think that Command should be a linear type, which should you
> more fun!
>
> On Tue, Mar 26, 2019 at 5:49 AM Artyom Shalkhakov <
> artyom.shalkha...@gmail.com> wrote:
>
>> I've made a gist:
>>
>> https://gist.github.com/ashalkhakov/c3577e97b20020fde31f84447fd1e056
>>
>> It actually works. It illustrates the basics (sequencing, bind, input and
>> output). Nice. It doesn't have Haskell's "return" though, but that is
>> pretty simple to add (it's something that "creates" IO where there is no IO
>> at all...).
>>
>> The interpreter is using a continuation in the end. I chose this style
>> because the closure-function (i.e. our continuation) can be passed around
>> freely, whereas with a flat unboxed type it is sometimes difficult for the
>> C compiler to figure out the size of the variable.
>>
>> On Tuesday, March 26, 2019 at 10:11:11 AM UTC+2, Artyom Shalkhakov wrote:
>>
>>> Hi Brandon,
>>>
>>> On Friday, March 22, 2019 at 8:49:29 PM UTC+2, Brandon Barker wrote:
>>>>
>>>> Hey Artyom,
>>>>
>>>> Thanks for the very interesting analysis and response.
>>>>
>>>>
>>> Glad you found it useful!
>>>
>>> On Fri, Mar 22, 2019 at 4:06 AM Artyom Shalkhakov <artyom.s...@gmail.com>
>>>> wrote:
>>>>
>>>>> Hi Brandon,
>>>>>
>>>>> This is a very lively discussion, thanks for bringing it up.
>>>>>
>>>>> On Friday, March 22, 2019 at 5:48:07 AM UTC+2, Brandon Barker wrote:
>>>>>>
>>>>>> And for what it's worth, here is an Idris program for haha using
>>>>>> Effects:
>>>>>>
>>>>>> module Main
>>>>>>
>>>>>>
>>>>>> import Effects
>>>>>> import Effect.StdIO
>>>>>>
>>>>>>
>>>>>> hello : Eff () [STDIO]
>>>>>> hello = let ha = StdIO.putStr "ha" in ha *> ha
>>>>>>
>>>>>>
>>>>>> main : IO ()
>>>>>> main = run hello
>>>>>>
>>>>>>
>>>>>>
>>>>>> It prints "ha" twice, despite being a strict language. I presume, but
>>>>>> am not sure, this is because the effect time requires it to be 
>>>>>> re-evaluated
>>>>>> each time.
>>>>>>
>>>>>>
>>>>>>
>>>>> Well, the type of "hello" says that the computation will use the STDIO
>>>>> effect as many times as is necessary. The way the computation is
>>>>> constructed, it is meant to issue commands in a given sequence.
>>>>>
>>>>> One peculiarity of PureScript is that of handling effects via the
>>>>> algebraic effects approach. It's not easy to do in a high-performance way,
>>>>> because you need a call/cc construct present in the language, and moreover
>>>>> a 'multi-shot' one at that (i.e. the continuation *may* be invoked zero,
>>>>> once or more times by the effect interpreter). In ATS a simpler way is to
>>>>> use template functions to define effects differently (e.g. during testing
>>>>> and during the actual execution) -- it's constrained compared to the
>>>>> call/cc for sure, but then you don't have to pay the price of the call/cc
>>>>> plumbing. Another thing about PureScript is that it uses row types to 
>>>>> track
>>>>> the set of effects that a given Eff computation may involve during its
>>>>> evaluation.
>>>>>
>>>>
>>>> Not that it will invalidate anything you just said, but the above code
>>>> was Idris, but they may be similar in this regard (not sure). I need to
>>>> look into call/cc more at some point - not very familiar with this idea.
>>>> But I like where you are going with templates in ATS!
>>>>
>>>
>>>
>>> Haha, right! I mixed them up. I do remember reading about effects in
>>> both languages! And I think they are pretty similar, except in Idris, you
>>> have a type-level list of effects, whereas in PureScript, it is instead a
>>> row of effects. So, pretty similar from the POV of using it. I think. :)
>>>
>>>
>>>>
>>>>> So in short, if we view the programs as creating commands, and then
>>>>> some kind of external interpreter that executes them, then it all matches
>>>>> up. The programs might be quite pure and non-side-effecting (except for
>>>>> non-termination aka infinite looping runtime exceptions), the interpreter
>>>>> will perform the effects. Here's a pseudocode for the interpreter:
>>>>>
>>>>> // the command sub-language
>>>>> datatype Command = Print of string | Nop | Seq of (command, command)
>>>>> extern
>>>>> fun runCommand (c:Command): void
>>>>> extern
>>>>> fun seq (c:Command, Command): Command
>>>>> extern
>>>>> fun cprint (s:string): Command
>>>>> implement
>>>>> seq (c1, c2) = Seq (c1, c2)
>>>>> implement
>>>>> cprint (s) = Print s
>>>>> // the interpreter itself
>>>>> implement
>>>>> runCommand (c) = case+ c of Nop => (*done!*) | Print s => print (s) |
>>>>> Seq (c1, c2) => (runCommand(c1); runCommand(c2))
>>>>>
>>>>> Now let's assume the Command is abstract for the rest of the program
>>>>> (and only the runCommand, seq and print are exposed). We can now write:
>>>>>
>>>>> val hello = let val h = cprint "hi" in seq (h, h) end // here. twice
>>>>> the effect!
>>>>> implement
>>>>> main0 () = runCommand hello
>>>>>
>>>>> The "hello" itself is free of side-effects (or so it seems to me!). We
>>>>> might need to lazily evaluate stuff here (e.g. to enable looping, where 
>>>>> you
>>>>> need to give the interpreter the chance to run side-by-side with your
>>>>> expression). Or we need a more poweful "seq" (i.e. the Haskell's "bind"
>>>>> operator for stitching together the commands such that the left-hand side
>>>>> has to be evaluated to a value that is then fed to the right-hand side --
>>>>> i.e. incrementally built-up as it's being evaluated by the interpeter).
>>>>>
>>>>> In Haskell, the type Command is termed "IO" (with an additional type
>>>>> parameter to signify the result type of the command) and the interpreter 
>>>>> is
>>>>> somewhere in the runtime system.
>>>>>
>>>>
>>>> Nice to see that the basis of an interpreter can be created so easily!
>>>> I guess to make it feasible to program in, in addition to the issues you
>>>> just mentioned, some primitive standard library functions would need to be
>>>> wrapped up as 'Command' functions just as you did with cprint; another way
>>>> to do this might be to ascribe certain effect types to these primitives
>>>> using e.g praxi. Functions that build on these primitives could then
>>>> accumulate effects - perhaps some effects could even be consumed, but not
>>>> sure. Also not sure how the interpreter would deal with some values have
>>>> more than one effect type: Haskell seems to use the idea of monad
>>>> transformers to get around this but I do not find it particularly
>>>> satisfying so far
>>>>
>>>
>>> In Haskell there exists special support for the IO monad in the runtime
>>> and in the compiler; without such support I don't think it will be feasible
>>> to program in this way (since we will have to pay the price for the
>>> construction of terms even in the simplest of cases!).
>>>
>>>>
>>>> Still need to look into effects and how to encode different effect
>>>> types - I seem to recall ATS actually had build in support for effects at
>>>> the type level at some point.
>>>>
>>>
>>> Well, in my post I was talking mostly about algebraic effect handlers,
>>> and in ATS we have effect types. The former I'm interested in mostly
>>> because of modular testing. The latter, I think, is used mostly for
>>> tracking the dynamic terms that can be safely erased from the program with
>>> no change to said program's behavior.
>>>
>>>
>>>> Do you have or plan on having a repo to play around with this idea? If
>>>> not I may try to start one (at some point).
>>>>
>>>
>>> Well, I'll post it as a gist on github. I think there does exist a
>>> connection between the algebraic effect handlers and function templates
>>> that I would like to pursue, but I'm short on time.
>>>
>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>>> On Thursday, March 21, 2019 at 11:33:35 PM UTC-4, Brandon Barker
>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Thu, Mar 21, 2019 at 8:18 PM gmhwxi <gmh...@gmail.com> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>> One can definitely build a monad-based library to support IO:
>>>>>>>>
>>>>>>>> absvtype IO(a:vt@ype) = ptr
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> If really using monads, would it also be reasonable to do (or
>>>>>>> ideally start at Functor and then build up to Monad):
>>>>>>>
>>>>>>> absvtype Monad(a:vt@ype) = ptr
>>>>>>>
>>>>>>> somewhat as discussed at
>>>>>>> https://groups.google.com/forum/m/#!msg/ats-lang-users/gLiMU29C77c/sIjtqzmCBAAJ
>>>>>>>
>>>>>>>
>>>>>>>> The problem with IO monad is that it is so broad. With linear types,
>>>>>>>> a programmer can specify a lot more precisely.
>>>>>>>>
>>>>>>>> I agree. But my limited and slowly changing experience suggests
>>>>>>> that IO is a good starting point to help ensure purity in the rest of 
>>>>>>> the
>>>>>>> code that doesn't have effects; IO can typically be refined later to
>>>>>>> different types of Effects, I suppose.
>>>>>>>
>>>>>>>
>>>>>>>> >>is that ATS doesn't (by default?) model an IO effect.
>>>>>>>>
>>>>>>>> No, it doesn't if you use the default library. But nothing prevents
>>>>>>>> you
>>>>>>>> from tracking IO effects in ATS.
>>>>>>>>
>>>>>>>
>>>>>>> So in this case, one would create an alternative 'main' that must be
>>>>>>> composed of IO values. But what is to stop somewhat from calling print 
>>>>>>> in a
>>>>>>> function returning an IO, for instance? Thus violating the IO contract.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> In the book you mentioned in your message, I was really thinking of
>>>>>>>> views for specifying memory layouts. With linear views, a programmer
>>>>>>>> can be very precise in describing what memory a function can
>>>>>>>> access/update.
>>>>>>>> Compared to state monads, this kind of precision is unmatched.
>>>>>>>>
>>>>>>>
>>>>>>> Agreed. Maybe a separate effect type for STDIO, STDIN, etc would be
>>>>>>> a better starting point. Even in Haskell, I've seen some authors frown 
>>>>>>> on
>>>>>>> State since it is, in their view, a bit dishonest and not much better 
>>>>>>> htan
>>>>>>> IO (or maybe not better at all; see "false purity" at
>>>>>>> https://www.fpcomplete.com/blog/2017/06/readert-design-pattern).
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> On Thursday, March 21, 2019 at 1:28:42 PM UTC-4, Brandon Barker
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Thursday, March 21, 2019 at 9:30:40 AM UTC-4, Brandon Barker
>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>> Hi Artyom,
>>>>>>>>>>
>>>>>>>>>> I'm also grappling with the issue of RT in this case as I'd so
>>>>>>>>>> far only thought about it in terms of function calls, but what you 
>>>>>>>>>> and
>>>>>>>>>> Vanessa say helped me to understand the issue. Though I haven't 
>>>>>>>>>> managed to
>>>>>>>>>> get ATS to have the same behavior as OCaml in the "let expression" 
>>>>>>>>>> above, I
>>>>>>>>>> suspect it is possible. The key phrase here seems to be 
>>>>>>>>>> "side-effecting
>>>>>>>>>> expression", and relates to the fact that functions in ATS can 
>>>>>>>>>> perform side
>>>>>>>>>> effects without having any effect type or IO monad ascribed to the 
>>>>>>>>>> value
>>>>>>>>>> (again, iirc).
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Well, maybe that isn't the real key - the real key, I now think,
>>>>>>>>> is that ATS doesn't (by default?) model an IO effect. In section 6.9 
>>>>>>>>> of
>>>>>>>>> http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/PDF/main.pdf
>>>>>>>>> it is mentioned that using both linear and dependent types may be 
>>>>>>>>> used to
>>>>>>>>> do this, though I think the suggestion here is for more than printing 
>>>>>>>>> to
>>>>>>>>> e.g. STDOUT.
>>>>>>>>>
>>>>>>>>> If anyone has looked at modeling/enforcing an IO-like effect type
>>>>>>>>> in ATS, I'd be interested to see it.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Perhaps tonight I should try out the same in Idris or PureScript,
>>>>>>>>>> which are not lazily evaluated by default but do use IO, to get a 
>>>>>>>>>> better
>>>>>>>>>> understanding.
>>>>>>>>>>
>>>>>>>>>> On Thursday, March 21, 2019 at 3:17:46 AM UTC-4, Artyom
>>>>>>>>>> Shalkhakov wrote:
>>>>>>>>>>>
>>>>>>>>>>> Hi Brandon,
>>>>>>>>>>>
>>>>>>>>>>> Admittedly I don't really understand what RT is, but from what I
>>>>>>>>>>> understand, in Haskell the expression like [print "ha"] is 
>>>>>>>>>>> basically a
>>>>>>>>>>> command to the top-level interpreter (which is the language 
>>>>>>>>>>> runtime) to
>>>>>>>>>>> perform an effect on the console (moreover, it will be evaluated on
>>>>>>>>>>> as-needed basis). Moreover, the ";" is itself another comand, the 
>>>>>>>>>>> explicit
>>>>>>>>>>> sequencing command, the meaning of which is "perform the left-hand 
>>>>>>>>>>> side
>>>>>>>>>>> effects, then perform the right-hand side effects". Such a command 
>>>>>>>>>>> is a
>>>>>>>>>>> value, so it can be passed as a value and reused as many times as is
>>>>>>>>>>> necessary. In ATS, the expression like [print "ha"] evaluates right 
>>>>>>>>>>> there
>>>>>>>>>>> to a void/"no value", and the ";" is also NOT a value at all, but 
>>>>>>>>>>> rather a
>>>>>>>>>>> "shortcut" syntax to a "let-in-end" form.
>>>>>>>>>>>
>>>>>>>>>>> I like to imagine an interpreter that sits in the Haskell's
>>>>>>>>>>> runtime. Values of IO type are commands to this interpreter. Typical
>>>>>>>>>>> Haskell IO-based programs are building up these commands as they 
>>>>>>>>>>> are being
>>>>>>>>>>> evaluated by the runtime. The runtime starts evaluation at the 
>>>>>>>>>>> "main"
>>>>>>>>>>> expression defined by the programmer.
>>>>>>>>>>>
>>>>>>>>>>> чт, 21 мар. 2019 г. в 03:45, Brandon Barker <
>>>>>>>>>>> brandon...@gmail.com>:
>>>>>>>>>>>
>>>>>>>>>>>> I'm a little rusty, so can't come up with many good examples.
>>>>>>>>>>>>
>>>>>>>>>>>> Apparently it is possible to do something like this in OCaml:
>>>>>>>>>>>>
>>>>>>>>>>>> implement
>>>>>>>>>>>> main0 () = {
>>>>>>>>>>>>   val () = let
>>>>>>>>>>>>     val ha = print("ha")
>>>>>>>>>>>>   in
>>>>>>>>>>>>     (ha; ha) // How to get two ha's here?
>>>>>>>>>>>>   end
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> After running the program, you would only see one "ha", which
>>>>>>>>>>>> violates RT.
>>>>>>>>>>>>
>>>>>>>>>>>> However, ATS doesn't seem to allow a sequence expression in the
>>>>>>>>>>>> "in" position of a let expression, as this doesn't compile. 
>>>>>>>>>>>> Admittedly I'm
>>>>>>>>>>>> just trying to see if ATS2 doesn't have RT in this particular 
>>>>>>>>>>>> case, but it
>>>>>>>>>>>> would also be good to know about the sequence expressions here.
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> You received this message because you are subscribed to the
>>>>>>>>>>>> Google Groups "ats-lang-users" group.
>>>>>>>>>>>> To unsubscribe from this group and stop receiving emails from
>>>>>>>>>>>> it, send an email to ats-lang-user...@googlegroups.com.
>>>>>>>>>>>> To post to this group, send email to
>>>>>>>>>>>> ats-lan...@googlegroups.com.
>>>>>>>>>>>> Visit this group at
>>>>>>>>>>>> https://groups.google.com/group/ats-lang-users.
>>>>>>>>>>>> To view this discussion on the web visit
>>>>>>>>>>>> https://groups.google.com/d/msgid/ats-lang-users/5eba6b86-4146-4ba2-a87f-f8c511d902f0%40googlegroups.com
>>>>>>>>>>>> <https://groups.google.com/d/msgid/ats-lang-users/5eba6b86-4146-4ba2-a87f-f8c511d902f0%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>>>>>>> .
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Cheers,
>>>>>>>>>>> Artyom Shalkhakov
>>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>> You received this message because you are subscribed to the Google
>>>>>>>> Groups "ats-lang-users" group.
>>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>>> send an email to ats-lang-user...@googlegroups.com.
>>>>>>>> To post to this group, send email to ats-lan...@googlegroups.com.
>>>>>>>> Visit this group at https://groups.google.com/group/ats-lang-users.
>>>>>>>> To view this discussion on the web visit
>>>>>>>> https://groups.google.com/d/msgid/ats-lang-users/3d13aac1-2f28-47af-afbd-6d9eced901db%40googlegroups.com
>>>>>>>> <https://groups.google.com/d/msgid/ats-lang-users/3d13aac1-2f28-47af-afbd-6d9eced901db%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>>> .
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Brandon Barker
>>>>>>> brandon...@gmail.com
>>>>>>>
>>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "ats-lang-users" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to ats-lang-user...@googlegroups.com.
>>>>> To post to this group, send email to ats-lan...@googlegroups.com.
>>>>> Visit this group at https://groups.google.com/group/ats-lang-users.
>>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/ats-lang-users/9ff2fb00-6790-4541-9bc0-0a949a0c46e3%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/ats-lang-users/9ff2fb00-6790-4541-9bc0-0a949a0c46e3%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>>
>>>>
>>>> --
>>>> Brandon Barker
>>>> brandon...@gmail.com
>>>>
>>> --
>> You received this message because you are subscribed to the Google Groups
>> "ats-lang-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to ats-lang-users+unsubscr...@googlegroups.com.
>> To post to this group, send email to ats-lang-users@googlegroups.com.
>> Visit this group at https://groups.google.com/group/ats-lang-users.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/ats-lang-users/73270adc-4327-470b-b900-ae20e3b36cea%40googlegroups.com
>> <https://groups.google.com/d/msgid/ats-lang-users/73270adc-4327-470b-b900-ae20e3b36cea%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to ats-lang-users+unsubscr...@googlegroups.com.
To post to this group, send email to ats-lang-users@googlegroups.com.
Visit this group at https://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ats-lang-users/CAPPSPLrWrYGDfx%3D5EGD9mU5ZHV%2BFXhuxFXqsJy2P8kSYr9L7gg%40mail.gmail.com.

Reply via email to