GithubHelp home page GithubHelp logo

carp-lang / carp Goto Github PK

View Code? Open in Web Editor NEW
5.4K 107.0 173.0 11.69 MB

A statically typed lisp, without a GC, for real-time applications.

License: Apache License 2.0

C 7.69% Haskell 90.69% Shell 0.94% Nix 0.13% PowerShell 0.13% Emacs Lisp 0.01% Python 0.41%
lisp language game-development games static typed repl gamedev functional-programming functional

carp's Introduction

Carp

Logo

Linux CI MacOS CI Windows CI

WARNING! This is a research project and a lot of information here might become outdated and misleading without any explanation. Don't use it for anything important just yet!

Version 0.5.5 of the language is out!

About

Carp is a programming language designed to work well for interactive and performance sensitive use cases like games, sound synthesis and visualizations.

The key features of Carp are the following:

  • Automatic and deterministic memory management (no garbage collector or VM)
  • Inferred static types for great speed and reliability
  • Ownership tracking enables a functional programming style while still using mutation of cache-friendly data structures under the hood
  • No hidden performance penalties – allocation and copying are explicit
  • Straightforward integration with existing C code
  • Lisp macros, compile time scripting and a helpful REPL

Learn more

Join the chat at https://gitter.im/eriksvedang/Carp

A Very Small Example

(load-and-use SDL)

(defn tick [state]
  (+ state 10))

(defn draw [app rend state]
  (bg rend &(rgb (/ @state 2) (/ @state 3) (/ @state 4))))

(defn main []
  (let [app (SDLApp.create "The Minimalistic Color Generator" 400 300)
        state 0]
    (SDLApp.run-with-callbacks &app SDLApp.quit-on-esc tick draw state)))

For instructions on how to run Carp code, see this document.

For more examples, check out the examples directory.

Maintainers

Contributing

Thanks to all the awesome people who have contributed to Carp over the years!

We are always looking for more help – check out the contributing guide to get started.

License

Copyright 2016 - 2021 Erik Svedäng

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

The regular expression implementation as found in src/carp_regex.h are Copyright (C) 1994-2017 Lua.org, PUC-Rio under the terms of the MIT license. Details can be found in the License file LUA_LICENSE.

carp's People

Contributors

babelchips avatar bagucode avatar chrisosaurus avatar croyzor avatar dbalan avatar efimero avatar eriksvedang avatar felipecrv avatar goodmind avatar grayjack avatar guberathome avatar hellerve avatar honix avatar jacereda avatar jl2 avatar leblowl avatar linkpy avatar mitchell-frost avatar muhammedzakir avatar nananas avatar opqdonut avatar rgkirch avatar scolsen avatar sdilts avatar spencerking avatar timdeve avatar tomsmeding avatar tversteeg avatar vertmo avatar xran-deex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

carp's Issues

May be something You'll be interesting in researching

unikernel

Have you considered Carp as a first unikernel friendly LISP? Unikernel applications have to be fast to restart, have low memory profile and usually they are "single threade". It seems like Carp can provide it all.

Links for research
https://github.com/rumpkernel/rumprun/
https://github.com/solo-io/unik

WebAssembly

LISPs like Clojure can't target WebAssembly because they need GC and WebAssembly still lacks it.
Carp can use LLVM to compile into WebAssembly.

Scala's dependent types paper 1 2

Not sure about that one but You might be interested since Carp also has type inference

Mkdir, touch unsafety

The mkdir and touch implementations in core.karp just concatenate the given name into a shell expression. Things like (mkdir "dir; malicious_program") will therefore not do the expected thing; this is a problem if user input is directly given to mkdir and/or touch.
I'd expect not to have to quote input when giving it to those functions.
Fix would be to use fork/execlp not sure how feasible that is from lisp?

possible bytecode refactor

looking at src/bytecode.c I see

// 'a' push lambda <literal>                                                    
// 'c' call <argcount>                                                          
// 'd' def <literal>                                                            
// 'e' discard                                                                  
// 'g' catch                                                                    
// 'i' jump if false                                                            
// 'j' jump (no matter what)                                                    
// 'l' push <literal>                                                           
// 'n' not                                                                      
// 'o' do                                                                       
// 'p' push nil                                                                 
// 'r' reset!                                                                   
// 't' let                                                                      
// 'u' end of function (process->function_trace_pos--)                          
// 'v' pop let scope                                                            
// 'x' direct lookup                                                            
// 'y' lookup <literal>                                                         
// 'q' stop                                                                     

and then throughout the code

  bytecodeObj->bytecode[*position] = 'a';    

would it be beneficial to refactor this?

we could represent the bytecode as an enum, that way instead of using the literal 'a' you could use lambda (we could even set the enum values to match the letters, so it is still printable).

we could instead use defines.

This could also just be busy work, what are your thoughts?

Suggestion: Adopt C++ name mangling conventions for better compatibility

Issue: It's not possible to encode all valid Lisp identifiers, type names differentiating overloaded functions, namespaces directly in C because C identifiers are very strict, so Carp is creating its own name mangling strategy.

Suggestion: adopt the C++ name mangling scheme.

The C++ name mangling strategy has two advantages: already exists and is understood by many tools.

Even Rust has adopted it https://github.com/rust-lang/rust/blob/76affa5d6f5d1b8c3afcd4e0c6bbaee1fb0daeb4/src/librustc_trans/back/symbol_names.rs#L358

Doc Request: no GC

hi,
The first feature on the list: "Automatic and deterministic memory management".

Could this be elaborated a bit more extensively? What are your strategies? What does Carp different then all the other languages that use either manual or automatic memory management?

Thanks

A program using references to arrays but nothing else produces invalid typedefs

This is a tracking issue for a known bug in Carp: when a function uses Arrays, but does not generate them, no typedef is emitted. This leads to errors in the C compiler. For an example see the following function:

(defn accumulate [arr]
   (let [acc 0]
     (do
       (for [i 0 (count arr)]
          (set! &acc (+ acc @(Array.nth arr i))))
       arr)))

It can be fixed currently by defining a bogus function that generates an array, for instance:

(defn bogus []
  [0.0])

Cheers

Compiling without core library - modularization of core library?

All the core registered c functions of carp are defined in core.h. That means it is not possible to compile a program which only uses parts of core.h by using the --no-core compiler flag and then loading individual carp modules.

A possible solution could be to split core.h into different modules, i.e. int_core.h for functions registered in Int.carp and so on. (Somehow the necessary stdlib headers would need to be included also) What are some good ways achieve a modular system?

Polymorphism ideas

As of #37 we now have contains?, array-contains?, string-contains?.

I see a few ways of handling this:

  1. don't, many lisps never handle this, so leave it be.
  2. have the contains? method test it's argument and dispatch to list-contains?, array-contains?, string-contains? - this works for builtin types but cannot be user extended.
  3. have contains operate via an interface that supports all the builtin types that can also be extended - I am unsure if Carp currently has the capability for this.

What are your thoughts?

Feedback wanted – Docs and type signatures

I've been pondering a good way to annotate top level forms with documentation and (optional) type signatures.

Here are some suggestion:

Style A

A doc and sig command.

(doc average "Calculates the average value of an Array of double:s.")
(sig average (λ [(Array Double)] Double))
(defn average [nums]
  <implementation>)

Style B

Reader macros.

^doc "Calculates the average value of an Array of double:s."
^sig (λ [(Array Double)] Double)
(defn average [nums]
  <implementation>)

They would probably expand to something like this:

(doc "Calculates the average value of an Array of double:s."
     (sig (λ [(Array Double)] Double)
          (defn average [nums]
            <implementation>)))

Style C

More flexible versions of def/defn.

(defn average [nums]
  (λ [(Array Double)] Double)
  "Calculates the average value of an Array of double:s."
  <implementation>)

Any better ideas?

I think all the versions above are passable but not immediately attractive. Does anyone have other suggestions to take into account?

Add all the math functions

@hellerve has added a whole lot of math functions to the Double module. The Float module is way behind though, and there are also probably a few useful functions left to add for all the different math modules (Int / Long / Float / Double).

Found unresolved generic type `(λ [(λ [&r12] r15), (Array r12)] (Array r15))`

Hi, I've being poking around with carp in repl, but unfortunately I don't seem to get it to produce output

Welcome to Carp 0.2.0
This is free software with ABSOLUTELY NO WARRANTY.
Evaluate (help) for more information.
鲮 (use Array)
鲮
鲮 (defn map [f xs]
       (let [ys []]
         (do
           (for [i 0 (count &xs)]
             (aset! &ys i (f (nth &xs i))))
           ys)))
鲮 (type map)
map : (λ [(λ [&r18] r15), (Array r18)] (Array r15))
鲮 (c map)
Found unresolved generic type '(λ [(λ [&r12] r15), (Array r12)] (Array r15))' at line 1, column 0 in 'REPL', can't print resulting code.


Found unresolved generic type '(λ [(Array r15)] ())' at unkown line, unknown column in 'Array.delete__UNSOLVED_VARIABLE template', can't print resulting code.



Found unresolved generic type '(λ [(Array r15)] ())' at unkown line, unknown column in 'Array.delete__UNSOLVED_VARIABLE template', can't print resulting code.


鲮

I suspect it's due to f being polymorphic, is that a limitation or am I overlooking something ?

are you guys planning to support enums?

in rust and other languages, have support for enumerations. which allows for creating types that
must match some planned types.

some syntax suggestions
no extra data -- nil or unit value
not sure what might be used other wise.
``
(defenum months [ january nil
febuary nil
march nil
april nil ]

;dont know what you guys use for generics
(defenum option [ Some T
None nil ]
``

envWithArgs fails on certain inputs

When trying to compile this—faulty—program:

(use Array)

(defn add-int [&x &y] (Int.+ (Int.copy x) (Int.copy y)))

(defn main []
  (do (println (Array.reduce add-int 0 [1 2 3 4 5]))))

the compiler dies with the error carp: src/Obj.hs:433:29-104: Non-exhaustive patterns in lambda. The line is envWithArgs, where a pattern match occurs in a lambda that is not exhaustive.

The line of the above program that triggers the bug is (defn add-int [&x &y] (Int.+ (Int.copy x) (Int.copy y))). Typing this in a REPL will also cause a crash.

Cheers

Carp in Docker

Struggled through a LOT of setup/config issues when putting Carp into a Docker image. (I have the Dockerfiles--both the carp image and the haskell one I build that it depends on--in a public Git repo if anyone wants to tell me if/how my config is borked--I'm not really a Haskeller so I'm very ready to admit that what I'm doing here is borked. https://bitbucket.org/TedNeward/Docker.git/carp and https://bitbucket.org/TedNeward/Docker.git/haskell, respectively.)

When I got everything to build, though, and try to run Carp against one of the examples ("basics.carp"), I get an error: hGetContents: invalid argument (invalid byte sequence). No idea how to fix this.

All I really want to do is play with Carp for a while, not build it from source--if there's a working binaries image I can grab, I'd do that in a heartbeat, but I don't see one anywhere....?

replace 'dont-remove-this-file'

The dont-remove-this-file file can be replaced by something more elegant, a simple .gitignore in the directory with the contents:

*
!.gitignore

will keep the directory empty at all times, but still in git.

Clojure-like :keywords

Have you considering acquiring clojure :keywords and maps? Comaprision by the pointer would produce a very efficient result in map lookups

handling errors in the implementation

Looking at the implementation for obj_new we see

Obj *obj_new(char tag) {                                                                                                                                                                                          
  Obj *o = malloc(sizeof(Obj));                                                                                                                                                                                   
  o->prev = obj_latest;                                                                                                                                                                                           
  o->alive = false;                                                                                                                                                                                               
  o->given_to_ffi = false;                                                                                                                                                                                        
  o->tag = tag;                                                                                                                                                                                                   
  o->meta = NULL;                                                                                                                                                                                                 
  obj_latest = o;                                                                                                                                                                                                 
  obj_total++;                                                                                                                                                                                                    
  if(LOG_ALLOCS) {                                                                                                                                                                                                
    printf("alloc %p %c\n", o, o->tag);                                                                                                                                                                           
  }                                                                                                                                                                                                               
  return o;                                                                                                                                                                                                       
}     

a call to malloc can fail

I would like to add some error handling here, if that suits you.

How would you like errors of this nature to be handled?
I am happy to just print error and exit the program (probably something stronger than an assert - as asserts can be compiled out).

Does IO.println expect String or &String?

IO.println is rather coy about what type it expects.

(defn main [] (IO.println "foo")) ; OK
(defn main [] (IO.println (Int.str 42))) ; ERROR: (Int.str 42): String, expected &String
(defn main [] (IO.println &(Int.str 42))) ; OK
(defn main [] (IO.println &"foo")) ; ERROR: (ref "foo"): &String, expected String

So which is it?!

Script for generating binary releases

By request I made a binary release of the current compiler (get it here).

It would be great if we had a shell script that copied the correct files to a folder and compressed the whole thing, removing the need for human intervention as much as possible.

Rewrite more of the template functions using plain Carp.

Now when we have interfaces it should be possible to rewrite some (most) of the Array functions using plain carp. This will clean up the compiler and make it less likely that a memory error slips in through the template generated C code.

Memory corruption

I am trying to write a matrix library. Here is the code so far:

(load "Array.carp")
(load "Vector.carp")

(defmodule Matrix
  (deftype MatrixFlat [rows Int, cols Int, data VectorN.VN])

  (defn init [r c data]
     (if (Int.= (* r c) (Array.count &data))
         (MatrixFlat.init r c (VectorN.VN.init (* r c) data))
         (let [zz 0.0
               data1 (Array.replicate (Int.* r c) &zz)]
           (MatrixFlat.init r c (VectorN.VN.init (Int.* r c) data1)))))

  (defn get [m r c]
    (let [data (VectorN.VN.v (MatrixFlat.data m))
          idx1 (+ (* (MatrixFlat.cols m) r) c)
          idx (Int.min (Int.dec (* (MatrixFlat.rows m) (MatrixFlat.cols m)))
                       idx1)]
      @(Array.nth data idx)))

  (defn set [m r c val]
    (let [data (VectorN.VN.v (MatrixFlat.data m))
          idx1 (+ (* (MatrixFlat.cols m) r) c)
          idx (Int.min (Int.dec (* (MatrixFlat.rows m) (MatrixFlat.cols m)))
                       idx1)]
      (Array.aset! data idx val)))

  (defn to-string [o]
    (string-join @"Matrix(rows = " (Int.str (MatrixFlat.rows o)) @", cols = "
                 (Int.str (MatrixFlat.cols o)) @", values = " 
                 (Array.str (VectorN.VN.v (MatrixFlat.data o))) @")      "))

  (defn add [m1 m2]
     (MatrixFlat.init (MatrixFlat.rows m1) (MatrixFlat.cols m1)
                      (VectorN.add (MatrixFlat.data m1) (MatrixFlat.data m2)))) 

  (defn sub [m1 m2]
     (MatrixFlat.init (MatrixFlat.rows m1) (MatrixFlat.cols m1)
                      (VectorN.sub (MatrixFlat.data m1) (MatrixFlat.data m2)))) 

  (defn mul [m a]
     (MatrixFlat.init (MatrixFlat.rows m) (MatrixFlat.cols m)
                      (VectorN.mul (MatrixFlat.data m) a))) 

  (defn div [m a]
     (MatrixFlat.init (MatrixFlat.rows m) (MatrixFlat.cols m)
                      (VectorN.div (MatrixFlat.data m) a))) 

  (defn matmul [m1 m2]
    (let [r1 (MatrixFlat.rows &m1)
          c1 (MatrixFlat.cols &m1)
          r2 (MatrixFlat.rows &m2)
          c2 (MatrixFlat.cols &m2)
          res (init r1 c2 [])]
      (do
        (for [i 0 r1]
          (for [j 0 c2]
            (let [s 0.0]
              (do
                (for [k 0 r2]
                  (set! &s (Double.+ s 
                                     (Double.* (get &m1 i k)
                                               (get &m2 k j))))) 
                (set &res i j s)))))
         res)))

  (defn chol [m res n]
     (do
       (for [i 0 n]
         (for [j 0 (Int.+ i 1)] 
           (let [s 0.0]
             (do
               (for [k 0 j]      
                 (set! &s (Double.+ s (Double.* (get res i k) (get res j k)))))
               (set res i j
                    (if (Int.= i j)
                        (Double.sqrt (Double.- (get m i i) s))
                        (Double./ (Double.- (get m i j) s) (get res j j))))))))
        @res))
  (defn cholesky [m]
    (let [n (MatrixFlat.rows &m)]
      (chol &m &(init n n []) n)))
)


(defn main []
  (let [m1 (Matrix.init 2 2 [4.0 -1.0 -1.0 4.0])
        m2 (Matrix.init 3 3 [25.0 15.0 -5.0 15.0 18.0 0.0 -5.0 0.0 11.0])
        m3 (Matrix.cholesky @&m2)]
    (do
      (Matrix.set &m1 0 0 5.0)
      (IO.println &(Double.str (Matrix.get &m1 0 0)))
      (IO.println &(Double.str (Matrix.get &m1 1 1)))
      (IO.println &(Matrix.to-string &m1))
      (IO.println &(Matrix.to-string &m2))
      (IO.println &(Matrix.to-string &m3)))))
     

when I build this project at the REPL everything is fine (I use '(load "Matrix.carp")', then '(build)')
everything is fine. When I run 'out/a.out' I get unexpected output like:

 $ out/a.out
5
4
Matrix(rows = 2, cols = 2, values = [5 -1 -1 4]
Matrix(rows = 3, cols = 3, values = [25 15 -5 15 18 0 -5 0 11]ZZZZZZZZZZZZZZZZ
Matrix(rows = 3, cols = 3, values = [5 0 0 3 3 0 -1 1 3]

I would have expected:

 $ out/a.out
5
4
Matrix(rows = 2, cols = 2, values = [5 -1 -1 4])
Matrix(rows = 3, cols = 3, values = [25 15 -5 15 18 0 -5 0 11])
Matrix(rows = 3, cols = 3, values = [5 0 0 3 3 0 -1 1 3])

Can you help me find out what's wrong? Many thanks in advance.

Mac OSX build issues

My work on #24 has left some users ( @daveyarwood ) unable to build, whereas @eriksvedang is still able to build.

Opening issue to track progress.

I am working on setting up travis-ci for mac, I have #53 waiting which adds travis linux builds.

Fails to compile on Linux

I forked your repo and managed to add some minor fixes to get it compiling under Linux including the spin demo @ paines@fd4c1bc. Unfortunately I do not understand how to create a pull request !

New install missing carp-repl?

Hi - I just discovered Carp and it looks awesome. I'm itching to try it out!

I just cloned this repo and ran cmake ., and it appeared to execute successfully:

$ cmake .
-- The C compiler identification is AppleClang 6.0.0.6000057
-- The CXX compiler identification is AppleClang 6.0.0.6000057
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/Carp

This created a bin/ folder with a few files in it:

$ ls bin
carp          carp-inferior carp.bat

NOTE: I moved /tmp/Carp to ~/Code/Carp at this point:

$ ls ~/Code/Carp/bin
carp          carp-inferior carp.bat

However, when I try to run carp, I get an error about bin/carp-repl not existing:

$ bin/carp
rlwrap: error: Cannot execute /Users/dave/Code/Carp/bin/carp-repl: No such file or directory

I get the same result when trying to run the example .carp files, and after including carp in my PATH.

Benchmarking examples

Since we have a new and shiny benchmarking module it would be great with some examples of how fast (or slow) different things are in Carp. Preferably the examples should be similar to what other languages often do, making it easier to compare between languages.

It would also be interesting to compare different approaches within Carp, for example direct mutation compared to using the updating-functions, and similar.

Failed to open dylib: "libglfw.so.3"

#:~/p/p/carp|master✓   
➤ bin/carp
λ> (load-lisp "examples/spin.carp")
ERROR: Failed to open dylib: "libglfw.so.3"
 ----------------------------------------------------------------
  3 load-dylib                     gl.carp 9:0
  2 load-lisp                      core.carp 365:0
  1 No meta data.
  0 load-lisp                      repl 1:0
 ----------------------------------------------------------------

λ> 
#:~/p/p/carp|master✓                                                                 
➤ whereis libglfw.so.3
libglfw.so: /usr/lib/libglfw.so /usr/lib/libglfw.so.2 /usr/local/lib/libglfw.so /usr/local/lib/libglfw.so.3

I'm not very experienced building on Linux. Is there something I'm missing?

Naming clashes

When defining variables that clash with typenames, we get spurious error from the C compiler, most notably when naming things string or pattern—which might be desirable names.

Minimum viable example:

(def string "hi")

(defn main []
  (IO.println string))

Please note that while string and pattern are most certainly the most notable examples, this also works with any other C type, e.g. uint8_t.

I guess this could be fixed by mangling variable names as well?

Cheers

Parsing λ on Windows.

I started working on Windows support but got stuck on the parser. It doesn't handle the lambda character λ out-of-the box like it does on Linux / Mac. Perhaps someone who is more knowledgeable about text encoding on Windows knows what's going on?

Error messages when starting carp repl

Can't understand type when registering '+'
Can't understand type when registering '-'
Can't understand type when registering '*'
Can't understand type when registering '/'
Can't understand type when registering '<'
Can't understand type when registering '>'
Can't understand type when registering '='
Can't understand type when registering 'mod'
Can't understand type when registering 'seed'
Can't understand type when registering 'random'
Can't understand type when registering 'random-between'
Can't understand type when registering 'str'
Can't understand type when registering 'from-string'
Can't understand type when registering 'mask'
Can't understand type when registering 'inc'
Can't understand type when registering 'dec'
Can't understand type when registering 'copy'
[TYPE ERROR] Trying to refer to an undefined symbol 'for' at line 9, column 9.
Can't understand type when registering '='
Can't understand type when registering 'copy'
Can't understand type when registering 'count'
Can't understand type when registering 'duplicate'
Can't understand type when registering 'cstr'
Can't understand type when registering 'str'
Can't understand type when registering 'chars'
[PARSE ERROR] "(source)" (line 9, column 10):
unexpected "'"
expecting "&", "@", "(", "[", digit, "-", "\"", "\\", letter or ")"

The REPL itself works. But I only get useful output for strings:
string _0 = strdup("Test");
Else I get nothing or error messages.

ASL 2.0 | MIT | BSD | Boost

Can you license this as a combination of:

  • ASL 2.0
  • MIT or 2 Clause BSD or Boost

for the compiler and

  • ASL 2.0
  • Boost

for the libraries.

Also it might be an idea to triple license it using ASL 2.0, Boost, either MIT or 2-BSD for compiler and standard library.

type system

What type system are you planning on using. will you support algebraic data types, typeclasses and monads?

Compiler error for explicit typing?

The following code

;; Test

(use IO)
(use Int)
(use String)

(def myvariable (the Int 5))

(defn main []
    (println ( ref(Int.str myvariable))))

gives

./out/main.c:196:18: error: initializer element is not a compile-time constant
int myvariable = _5;

The compiler allows main to return non-ints

According to the compiler, this is a valid Carp program:

(defn main []
   @"Hi there!")

Compiling it will result in the following C code:

int main() {
    string _4 = "Hi there!";
    string *_4_ref = &_4;
    string _5 = String_copy(_4_ref);
    return _5;
}

The generated C code tries to return a string/char * from a function declared int. The C compiler will probably complain, although it might only be a warning.

A naive idea to fix this problem: introduce main as a fix point to the type checker (i.e. make it common knowledge that main is always of type [] -> Int. This way at least the type checker would fail, which is better than having the C compiler handle it.

Cheers

Move tests from 'examples' to 'test'

Since we have a new and shiny testing library it would be awesome if all the old "tests" in the example folder would be moved to the 'test' folder and converted to using the library instead of just dumping a bunch of text to stdout. I'll do this eventually but if anyone wants to start the job, please go ahead. I can assist with guidance.

Wrap regex library

As mentioned in #94, we need to wrap a regex library. I personally would like to wrap something that is as portable as possible. I’ve used regex.h in the past, but that isn’t available on Windows (I believe).

Things to consider:

  • PCRE would be great
  • If we add a library dependency, how should we ship it?

Any preferences/ideas are appreciated.

Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.