4 ms·
This is pretty cool and interesting, but I'm curious how they can claim purity if they still permit evaluation of code written in Java or other JVM languages, e
by lexicalscope 11y ago
This is pretty cool and interesting, but I'm curious how they can claim purity if they still permit evaluation of code written in Java or other JVM languages, even if the types have to be redeclared. In other words, I'm curious if they are permitting execution of "impure" functions outside of a monad or unsafe function if the type has been redeclared. May have to pull it down and have a look.
- duaneb 11y agoI would imagine you could have some combination of unsafePerformIO + an exception handler.
- michaelsbradley 11y agoHere's a write-up from 2013, Frege: Hello Java: http://mmhelloworld.github.io/blog/2013/07/10/frege-hello-java/ http://mmhelloworld.github.io/blog/2013/07/10/frege-hello-ja...
- reirob 11y agoOn the related Reddit thread [0] a commenter links to a very nice blog that evaluates Frege [1] in a very succinct way. To answer your question by quoting this blog post: "Wrapping mutable Java stuff in Frege means that everything will end up in an ST monad, which is almost always IO. That means that using Java’s HashSet will force anything that uses that to be in the IO monad itself. So there goes purity and referential transparency, which are some of the best parts of Haskell in the first place." [0] https://www.reddit.com/r/haskell/comments/3gr7y6/infoq_frege_a_haskell_for_the_jvm/cu0vj5m https://www.reddit.com/r/haskell/comments/3gr7y6/infoq_frege... [1] http://taylor.fausak.me/2015/06/25/frege-a-jvm-haskell/ http://taylor.fausak.me/2015/06/25/frege-a-jvm-haskell/ EDIT: formatting
- lexicalscope 11y agoThanks for this. This is a bit misleading though I think, as you can actually unwrap and ST unlike an IO - my most common use for ST is actually to use a mutable object in a case where it's inefficient to keep copying immutable (e.g.: large vector or matrix manipulations) - then when you're done the ST monad can be unwrapped and you get the final structure - the entire function remains pure but inside of it, there are calculations that rely on state - but no state enters or leaves the function per say. This would mean using a hash set would be out of the question _for passing around outside of an ST monad_ but you could actually use it internally within functions.
- voxfrege 11y ago> This would mean using a hash set would be out of the question _for passing around outside of an ST monad_ but you could actually use it internally within functions. Yes, but this is what the author was saying: you end up writing your code in ST. Remeber, there is no (general) way to freeze a mutable collection that was passed and then use it as if it was immutable. There can be a dozen different threads be busy modifying it. However, as immutable objects are becoming more mainstream even in Java, there will still plenty of opportunities to make polyglot JVM programs employing pure code. Just not with the JAVA collection classes.
- zxexz 11y agoThe compiler isn't very 'user-friendly', but if you're literally looking for "Haskell on the JVM" and don't care about speed, Frege is a lot of fun once you get used to it. Impure functions/variables must be wrapped in a monad (ST) (take a look at [0]. Frege is almost identical to Haskell, but with a few differences [1] [0] https://github.com/Frege/frege-native-gen/issues/14 https://github.com/Frege/frege-native-gen/issues/14 [1] https://github.com/Frege/frege/wiki/Differences-between-Frege-and-Haskell https://github.com/Frege/frege/wiki/Differences-between-Freg...
- evincarofautumn 11y agoAllowing foreign code doesn’t change the purity of the language. By default in Haskell, an FFI declaration must be in IO, e.g: -- int frob(int, char*) foreign import ccall "frob" frob :: Int -> CString -> IO Int If you know such a function to be pure, you can use unsafePerformIO to tell the type system: refrob :: Int -> CString -> Int refrob x y = unsafePerformIO (frob x y) If you lie to the type system and tell it that an impure function is pure, then all bets are off.
- lexicalscope 11y agoI guess that was my question - if they are making it use FFI as in Haskell, since it's Haskell-like not actual Haskell, or if it's something else that's specific to their JVM version.
- voxfrege 11y agoIt is an FFI, though with different syntax, and much richer. Not only functions, but also foreign (in Frege its called "native") types. Which is indispensable IMHO when you interface a OO language where everything is classes and interfaces. The different syntax should not be a big issue, as Haskell code that uses FFI targeting C is per se not portable.
- voxfrege 11y ago> If you know such a function to be pure, you can use unsafePerformIO to tell the type system Better yet, if you know it to be pure, you can give it an appropriate type and just use it in pure code, like: pure native cos java.lang.Math.cos :: Double -> Double which should be roughly equivalent to: foreign import jvm "java.lang.Math.cos" cos :: Double -> Double except that no Haskell compiler that I know implements the "jvm" calling convention, for obvious reasons. In fact, all primitive operations, types and so on are defined this way in the Frege Prelude.
- dustingetz 11y agoWorth pointing out that this approach isn't particularly helpful when wrapping mutable Java objects, because Java land still has a reference and can/will mutate the object right underneath us. So we still need to write our Fredge code in ST.