kindl/Hypatia

Building

Closed this issue · 9 comments

Hey, as an Elm fan, and trying to learn Roblox (I already have Lua experience from playing with Corona, now Solar2D), I fell in love with your language immediately.

However, I suck at Haskell. I've tried installing cabal on my Mac, and running configure/build/install/run, etc. but keep getting:

Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: hypatia-0.1.0.0 (user goal)
[__1] next goal: base (dependency of hypatia)
[__1] rejecting: base-4.14.0.0/installed-4.14.0.0 (conflict: hypatia =>
base<4.13)
[__1] skipping: base-4.14.0.0, base-4.13.0.0 (has the same characteristics
that caused the previous version to fail: excluded by constraint '<4.13' from
'hypatia')
[__1] rejecting: base-4.12.0.0, base-4.11.1.0, base-4.11.0.0, base-4.10.1.0,
base-4.10.0.0, base-4.9.1.0, base-4.9.0.0, base-4.8.2.0, base-4.8.1.0,
base-4.8.0.0, base-4.7.0.2, base-4.7.0.1, base-4.7.0.0, base-4.6.0.1,
base-4.6.0.0, base-4.5.1.0, base-4.5.0.0, base-4.4.1.0, base-4.4.0.0,
base-4.3.1.0, base-4.3.0.0, base-4.2.0.2, base-4.2.0.1, base-4.2.0.0,
base-4.1.0.0, base-4.0.0.0, base-3.0.3.2, base-3.0.3.1 (constraint from
non-upgradeable package requires installed instance)
[__1] fail (backjumping, conflict set: base, hypatia)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: base, hypatia

Any hints? I'm assuming I need to build her first before I can run her as a runtime/shell command.

kindl commented

Hey Jesse, thank you for your kind words!
Just out of curiosity, how did you stumble on this language?
I kind of just uploaded the source to show my friends who wanted to see what I'm working on.
I appreciate your courage to try out the language!

That error message looks more confusing than it actually is.
It says, that you have a newer standard library (base-4.14.0.0) installed, but the package file (hypatia.cabal) lists the dependency base < 4.13.
You can try to use the cabal flag --allow-newer to allow newer versions.
Instead, you can also download the newest commit where I changed the package file for you.

Yes cabal install should build the package and create an executable hypatia in your path.
I haven't tried to build it with a newer version of base yet.
Let me know if it works.

I did Advent of Code 2018 and 2019 in Elm, and was planning to CRUSHING 2020 in Elm again. However, upon a walk in the woods with the family, my younger daughter was like "You should do Roblox and Lua". I already knew enough Lua from my Corona days, so was like "next year" and she was like "You have to wait a whole year!? That's dumb. Why not now?" And I was like... "yeah... why not now?". I made it to Day 3 in 2018 and 2019, and this year to Day 6!!! I had fun visualizing trees for Day 3 in Roblox. I'm not familiar with 3D beyond college, so it was fun to learn about vector math and collisions, yadda yadda. While I don't play Roblox, definitely plan on exploring it more since it's much easier to play in vs Minecraft. That and my kid demands I help her code stuff and build stuff in Blender.

I had built a Lodash/Folktale (JavaScript) style library for Lua https://github.com/JesterXL/luafp so figured I'd survive their bs desire of for loops... and it didn't go as planned. Their use of coroutines is BRUTAL. I found a Promise (Future) implementation that helped a TON https://eryn.io/roblox-lua-promise/

... however, after Day 2, I was like, dude, I hate this. I mean, it's fun, but if the code grew beyond basic examples, I had no good strongly typed event bus, no good Redux like state framework, and side effects/race conditions everywhere.

So I started googling for "lua fp" and found a ton of links and articles about compile-to-lua options and I zero'd in on the FP ones. While Amulet looks cool, it doesn't compile using stack on my Mac, and yours was... well, it's just more "me", more Elm, more simple, but still the good parts of FP. Amulet is all higher-kinded type's + infix operator happy and feels OCAML ish, not really ML esque. I mean I like it, no doubt, but yours is better.

I'm on an M1, so my assumption is everything on the planet is running under Rosetta2... :: shrugs ::

Thanks a ton for the update! Ok, trying....

Ok, progress. It gets to compilation, but can't find modules/files that are clearly there? I've tried 3 different ghc's via ghcup just in case.

src/Main.hs:5:1: error:
    Could not find module ‘Syntax’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
  |
5 | import Syntax
  | ^^^^^^^^^^^^^

src/Main.hs:6:1: error:
    Could not find module ‘Compiler’

Actually interesting tidbit at bottom:

src/Main.hs:5:1: error:
    Could not find module ‘Syntax’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
  |
5 | import Syntax
  | ^^^^^^^^^^^^^

src/Main.hs:6:1: error:
    Could not find module ‘Compiler’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
  |
6 | import Compiler
  | ^^^^^^^^^^^^^^^

src/Main.hs:7:1: error:
    Could not find module ‘Transformations’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
  |
7 | import Transformations
  | ^^^^^^^^^^^^^^^^^^^^^^

src/Main.hs:8:1: error:
    Could not load module ‘Parser’
    It is a member of the hidden package ‘ghc-8.8.4’.
    Perhaps you need to add ‘ghc’ to the build-depends in your .cabal file.
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
  |
8 | import Parser hiding (modDecl)
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CallStack (from HasCallStack):
  die', called at ./Distribution/Client/ProjectOrchestration.hs:1041:55 in main:Distribution.Client.ProjectOrchestration
cabal: Failed to build hypt-0.1.0.0-91d47665.

Specifically Perhaps you need to add ‘ghc’ to the build-depends in your .cabal file..

Success! I had some Haskell kids at work help.

  1. cd into fresh download
  2. run stack init
  3. run stack build
  4. run stack install
  5. figure out path issues, lelz
  6. hypatia now compiles .hyp files to .lua!

God.... you even generate curried functions, I love this.

Interesting, why do you not compile the main Native.hyp; is that because those methods and types are built into the Love 2D engine? Like in the outputted Lua it shows:

local Native = require "Native"

Is that some class that Love2D has built-in?

Update: Oh... lol

-- NOTE the Native module is not written
-- If there are more than one Native module

... but... why?

Update 2: Oh wait, I think I figured it out. You already have a Native.lua in there, and that Native.hyp is more like a... strongly typed interface/header file to it, ya?

So rad, Hypatia running in Roblox. I gotta figure out how to convert your

require "some file"

to

require(script.Parent.SomeFile)

... but beyond that, I can write Hypatia, compile, fix requires's, and Rojo syncs the Lua into Roblox! I can then call the methods that Main.hyp exposes.

Lots to figure out regarding how I use print (i.e. write) and deal with their coroutine insanity, but beyond that, this is so sick! Thanks again.

Button code for hello world (I think my script's write runs when the script runs; not sure how to make functions with no parameters yet):

import Common.Array(map)
import Native(Numeral, Text, (+), write)
addOne x = x + 1

numsToStrings = map addOne

saySup = write "Sup from Hypatia, sucaka! OH YEAH, Hypatia running in t3h Roblox, BOOYAAAAAA!!11oneone"

It mostly compiles correctly, I just fix the require to be Roblox friendly:

local Scratch = {}
local Common_Array = require(script.Parent.Common_Array)
local Native = require(script.Parent.Native)
Scratch.addOne = function(x)
                 return Native.plus(x)(1.0)
                 end
Scratch.saySup = Native.write("Sup from Hypatia, sucaka! OH YEAH, Hypatia running in t3h Roblox, BOOYAAAAAA!!11oneone")
Scratch.numsToStrings = Common_Array.map(Scratch.addOne)
return Scratch

Then the buttons can either import it and invoke functions (Button hello):

script.Parent.MouseClick:Connect(function()
	local Scratch = require(workspace.Parent.ReplicatedStorage.Source.lua.Scratch)
	Scratch.saySup()
end)

Button array map 1 plus:

script.Parent.MouseClick:Connect(function()
	local Scratch = require(workspace.Parent.ReplicatedStorage.Source.lua.Scratch)
	print(Scratch.numsToStrings({1, 2, 3})[1])
end)

😄🤘🏼🎉

Screen Shot 2020-12-09 at 8 42 28 PM

Screen Shot 2020-12-09 at 8 44 18 PM

Screen Shot 2020-12-09 at 8 47 03 PM

Screen Shot 2020-12-09 at 8 49 46 PM

kindl commented

Hey Jester,

Well done, you figured out quite a lot!

I updated Haskell to see what happens if I try to build with a newer version.
Cabal has changed significantly because it switched to a new style of installing packages.
It seems that now all modules have to be listed explicitly.
I changed the package file and hypatia should also build with cabal now.

Yes, exactly. I needed a simple way of calling Lua and Love 2D functions.
A hypatia file with Native in its name is not compiled and could be seen as a "header file" that contains types.
One would write the content of the corresponding Lua file by hand.
I made this clearer in a comment.

Just in case: Hypatia is strict, so you have to be careful with leaving out parameters
fix f x = f (fix f) x
and
fix f = f (fix f)
are not the same, the latter will loop forever.
But in your case, it worked with map addOne.

Have fun exploring!