StanzaOrg / lbstanza-old

L.B. Stanza Programming Language
Other
216 stars 23 forks source link

[FEATURE REQUEST] a tag for pure / referentially transparent functions #43

Closed ewtoombs closed 6 years ago

ewtoombs commented 6 years ago

There already exists a tag that hints the compiler to do tail optimisation (defn*). I figure there could also be a tag that tells the compiler to fail if the function is not pure. I would find such a feature enormously useful for compile time error checking of functions I write and for identifying which functions in an unfamiliar API do not have any side effects / will always produce the same result given the same input. I'll give an example. In it, I'll use defn to mean the function is not necessarily pure, and defn+ to mean that it is.

defn+ pure_example (a:Double, b:Double, c:Double) -> Double :
    ((- b) + sqrt(b * b - 4 * a * c) / (2 * a)
defn impure_example (a:Double, b:Double, c:Double) -> Double :
    println("a=%_ b=%_ c=%_" % [a, b, c])
    ((- b) + sqrt(b * b - 4 * a * c) / (2 * a)

This would compile. If the second function's tag were defn+, though, it would not compile.

CuppoJava commented 6 years ago

This is something that we also desire, but may have to push until much later because there's significant fundamental research that needs to be done. The problem is that Stanza's multimethod system currently allows for too much flexibility to make such a tagging system easy-to-use.

defn+ sum-ints (xs:Seqable<Int>) : 
  var accum = 0
  for x in xs do : 
    accum = accum + x
  accum

It is unclear whether the above code is pure or not, as it depends on whether iterating through the 'xs' sequence contains side effects. A fully automatic analysis is probably impossible, and research needs to be done on how to provide a way for the user to state that xs can be iterated without side-effects.

ewtoombs commented 6 years ago

I see, @CuppoJava . I'm so glad you agree this would be useful. Well, as a compromise, all of the places where it is difficult to implement, you could just provisionally call such operations impure and implement defn+ just in all of the places where it is easy to tell whether the function is pure. So, multimethods and Seqable<Int> can be provisionally considered impure even though there may be a way to classify them as pure when they actually are. It would be a start, and I would still find this useful.