Print elm-syntax declarations as moonbit code.
To try it out, you can
run this script.
import Elm.Parser
import ElmSyntaxToMoonbit
"""module Sample exposing (..)
plus2 : Float -> Float
plus2 n =
n + ([ 2.0 ] |> List.sum)
"""
|> Elm.Parser.parseToFile
|> Result.mapError (\_ -> "failed to parse elm source code")
|> Result.map
(\syntaxModule ->
[ syntaxModule ]
|> ElmSyntaxToMoonbit.modules
|> .declarations
|> ElmSyntaxToMoonbit.moonbitDeclarationsToModuleString
)
-->
Ok """...
pub fn sample_plus2(n: Double) -> Double {
basics_add(n, list_sum_float(@list.of([2.0])))
}
"""- not supported are
- ports that use non-json values like
port sendMessage : String -> Cmd msg, glsl, phantom types,==on a generic value elm/file,elm/http,elm/browser,elm-explorations/markdown,elm-explorations/webgl,elm-explorations/benchmark,elm/regex(because no support inmoonbitlang/core),elm-explorations/linear-algebra(because no support inmoonbitlang/core)Task,Process,Platform.Task,Platform.ProcessId,Platform.Router,Platform.sendToApp,Platform.sendToSelf,Random.generate,Time.now,Time.every,Time.here,Time.getZoneName,Bytes.getHostEndianness- extensible record types outside of module-level value/function declarations. For example, these declarations might not work:
Allowed is only record extension in module-level value/functions, annotated or not:
-- in variant value type Named rec = Named { rec | name : String } -- in let type, annotated or not let getName : { r | name : name } -> name
In the non-allowed cases listed above, we assume that you intended to use a regular record type with only the extension fields which can lead to moonbit compile errors if you actually pass in additional fields.userId : { u | name : String, server : Domain } -> String
- elm's
Char.toLocale[Case]functions will just behave likeChar.to[Case] - elm's
VirtualDom/Html/Svg.lazyNfunctions will still exist for compatibility but they will behave just like constructing them eagerly
- ports that use non-json values like
- dependencies cannot internally use the same module names as the transpiled project
- the resulting code might not be readable or even conventionally formatted and comments are not preserved
Please report any issues you notice <3
- it has first-class support for wasm (and native)
- it feels like a superset of elm which makes transpiling and "ffi" easier
- it supposedly has fast compile times (I have yet to verify this claim)
- the language is bloated
- the language is very young and tooling like the build CLI are fragile
- the language's promotion has made overly big claims and has the classic AI bullshit
- the ecosystem is tiny so you will likely need to write your own FFI wrappers and similar
An example can be found in example-hello-world/.
In your elm project, add moon.pkg
options("is-main": true, "warn-list": "-1-6-71")and moon.mod.json
{"name": "your_project_name"}(If you know of a simpler setup, please open an issue)
and a file main.mbt that uses elm.mbt:
mod elm
print(your_module_your_function("yourInput"))where your_module_your_function(firstArgument, secondArgument) is the transpiled elm function Your.Module.yourFunction firstArgument secondArgument. (If the value/function contains extensible records, search for your_module_your_function_ with the underscore to see the different specialized options)
Run with
moon run .If something unexpected happened, please report an issue.
In the transpiled code, you will find these types:
- elm
Bool(TrueorFalse) → moonbitBool(trueorfalse),Char('a') →Char('a'),( Bool, Char )→( Bool, Char ) - elm
Ints will be of typeInt64. Create and match by appendingLto any number literal or usingInt::to_int64/Int64::from_int - elm
Floats will be of typef64. Create and match by using any number literal with a decimal point - elm
Strings (like"a") will be of the custom typeStringString. Create from literals or other string slices with (StringString::One("a")). Match withyour_string if string_string_string_equals_stringing(your_string, "some string") - elm records like
{ y : Float, x : Float }will be of typeGeneratedXY<f64, f64>with the fields sorted and can be constructed and matched with{ x: _, y: _ }.record.xaccess also works - elm
Lists will be of type@list.List. Create and match with the help of@list/List:: - elm
Arrays will be of type@immut/array.Array. Create and match with the helpers in@immut/array - elm
Sets will be of type@immut/sorted_set.SortedSet. Create and match with the helpers in@immut/sorted_set - elm
Dicts will be of type@immut/sorted_map.SortedMap. Create and match with the helpers in@immut/sorted_map - elm
Json.Encode.Value/Json.Decode.Values will be of typeJson. Create and match with the help of@json./Json:: - elm
Bytes.Byteswill be of typeBytes. Create and match with the help of@bytes/Bytes:: - a transpiled elm app does not run itself.
An elm main
Platform.workerprogram type will literally just consist of fieldsinit,updateandsubscriptionswhere subscriptions/commands are returned as a list ofPlatformSubSingle/PlatformCmdSinglewith possible elm subscriptions/commands in a choice type. It's then your responsibility as "the platform" to perform effects, create events and manage the state. For an example see example-worker-blocking/ & example-worker-concurrent/
- try and benchmark switching
Stringrepresentation fromOne &str | Append String Stringto(StringBuilder) -> StringBuilder - if lambda is called with a function, always inline that function
- your idea 👀