Code Monkey home page Code Monkey logo

sci's People

Contributors

bobisageek avatar borkdude avatar bytesguy avatar djblue avatar erdos avatar holyjak avatar ikappaki avatar ikitommi avatar jeroenvandijk avatar justone avatar kbaba1001 avatar kwrooijen avatar lilactown avatar lispyclouds avatar lread avatar mrebbinghaus avatar patrick-galvin avatar pez avatar pmonks avatar raymcdermott avatar rickmoynihan avatar rmschindler avatar signspice avatar sirwobin avatar sogaiu avatar sritchie avatar tiensonqin avatar victorb avatar viebel avatar wilkerlucio 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

sci's Issues

add tests for calling a non-function or an expression which results in a function

Transcript:

borkdude@MBA2015 ~/Dropbox/dev/clojure/babashka (master*) $ echo 'nil' | lein bb "(1 2 3)"
Cannot call 1 as a function.
borkdude@MBA2015 ~/Dropbox/dev/clojure/babashka (master*) $ echo 'nil' | lein bb '("foo" 2 3)'
Cannot call "foo" as a function.
borkdude@MBA2015 ~/Dropbox/dev/clojure/babashka (master*) $ echo 'nil' | lein bb "({:a 1} 2 3)"
3
borkdude@MBA2015 ~/Dropbox/dev/clojure/babashka (master*) $ echo 'nil' | lein bb "((hash-map :a 1) 2 3)"
3
borkdude@MBA2015 ~/Dropbox/dev/clojure/babashka (master*) $ echo 'nil' | lein bb "((hash-map :a 1) :a 2)"
1

bug with anonymous functions

This works:

$ echo '[1 2 3]' | ./bb '(map-indexed #(vector %1 %2) *in*)'
([0 1] [1 2] [2 3])

but this doesn't:

$ echo '[1 2 3]' | ./bb '(map-indexed #(do [%1 %2]) *in*)'

There also seems a bug with var-args:

(apply (fn [& xs] xs) 1 2 [3 4])

the symbol 'comment' does not get evaluated

version
babashka v0.0.18

platform
Ubuntu 16.04

problem
when trying to use a function with an argument called "comment" the actual value of the argument is ignored and it is used as a 'comment' object

repro
file repro.bb:

(defn comment-bug [comment]
  (println (type comment))
  (println comment))

(comment-bug *in*)

then execute:

$ bb --stream -io -f ~/repro.bb << EOF
please print this
EOF

expected output
java.lang.String
please print this

actual output
clojure.lang.Symbol
comment

more (maybe meaningless) information
this: bb --stream -io -e '(def comment *in*) (println comment)'
and this bb --stream -io -e '(def comment "in") (println comment)'

produce a similar bug

error when using recursive function with no args

(def c (atom 0))
(defn hello []
  (swap! c inc)
  (if (< @c 100) (hello) @c))
(println (hello))
java.lang.Exception: unexpected: clojure.lang.AFunction$1@1102b2b10 [at line 5, column 1]

Why don't we see this error when using 1 argument?

./bb '(defn hello [x]
  (if (< x 2400) (hello (inc x)) x))
(hello 0)'
2400

Note about dealing with stack overflows, use trampoline:

(defn hello [x]
  (if (< x 10000) #(hello (inc x)) x))
(println (trampoline hello 0))

Maybe with a trick we might be able to use trampoline for recursive functions under the hood.

resolve symbols at "compile" time rather than interpretation time

user=> (require '[sci.core :as sci])
nil
user=> (def f (sci/eval-string "#(< % 10)"))
#'user/f
user=> (f 11)
false
user=> (def f (sci/eval-string "#(x % 10)"))
#'user/f
user=> (f 11)
Exception Could not resolve symbol: x  sci.impl.interpreter/resolve-symbol (interpreter.cljc:159)

That's likely also beneficial for performance.

Adding vars to namespace 'clojure.core don't get merged in

sci.impl.main=> (sci/eval-string "(println :hello)" {:namespaces {'clojure.core {'println println}}})
ExceptionInfo Could not resolve symbol: println [at line 1, column 2]  clojure.core/ex-info (core.clj:4739)

Workaround for now: add these vars to :bindings.

Allow `pr-str` to be used

(sci/eval-string "(pr-str \"kikka\")")
; Syntax error (ExceptionInfo) compiling at ...
; Could not resolve symbol: pr-str [at line 1, column 2]

implement recur

We might go about it as follows:

(defn do-recur!
  [f & args]
  (let [ret (apply f args)]
    (if-let [m (meta ret)]
      (if (:sci.impl/recur m)
        (recur f ret)
        ret)
      ret)))

(defn recur! [& args]
  (with-meta args
    {:sci.impl/recur true}))

(defn hello [x]
  (if (< x 10000) (recur! (inc x)) x))

(println (do-recur! hello 0)) ;;=> 100000

and use do-recur! instead of apply when calling functions.

problem with `&env`

(defmacro let-bindings []
  (zipmap (map (fn [sym]
                 (list 'quote sym)) (keys &env)) (keys &env)))

(let [x 1 y 2] (println (let-bindings)))

(defn foo [x y z]
  (println (let-bindings)))

(foo 1 2 3) ;; <- problematic

The last call is problematic. We probably should mark some symbols as implementation details.

:allow option

Implement :allow option to only allow certain functions/macros.

Support for evaluating direct source code & fn*

Would be great if sci also supported also unqualified source code as input, maybe sci.core/eval? Currently, a hop via pr-str is needed. Also, fn* is not supported:

Current status

sci:

((sci/eval-string (pr-str `#(< 10 % 18))) 17)
;Syntax error compiling at (src/malli/core.cljc:575:1).
;Could not resolve symbol: fn*

eval:

((eval `#(< 10 % 18)) 17)
; => true

((eval (read-string (pr-str `#(< 10 % 18)))) 17)
; => true

Proposed:

((sci/eval `#(< 10 % 18)) 17)
; => true

((sci/eval-string (read-string (pr-str `#(< 10 % 18)))) 17)
; => true

support &env and &form in macros

E.g. it would be nice if this worked:

(defmacro lets []
  (zipmap (map (fn [sym]
                 (list 'quote sym)) (keys &env)) (keys &env)))

(println
 (let [x 1 y 2]
   (lets))) ;;=> {x 1, y 2}

Not super high priority probably.

&form is mostly used for either error reporting or capturing form metadata

Awesome project!

I really love this project and I hope to be able to contribute.
in the README:

You want to evaluate code from user input, but eval isn't safe or simply doesn't work.

Could you elaborate about what are the situations in which eval doesn't work?
I guess that when we compile a clojure program with GraalVM, eval doesn't work. Right?

Is it something essential to GraalVM? Could eval be available some day on GraalVM? Could we image a super fast Clojure REPL?

Please share as much details as you can ...

make usable from JS / deploy to NPM?

After compiling to JS with advanced this works:

$ node
Welcome to Node.js v12.8.0.
Type ".help" for more information.
> x = require('./out/main.js');
{ sci: { core: { eval_string: [Function] } } }
> eval_string = x.sci.core.eval_string
[Function: bx] { a: [Function], b: [Function], h: 2 }
> eval_string("(defn foo [] 1) (foo)")
1

Rationale

Is this actually useful for anyone?

API

What should a proper JS API look like and how do we get this from CLJS?

Function return values

Functions returned from SCI are CLJS functions. These are not directly callable from JS but you can use them like this: f.call(null, 1,2,3). What should we do to fix this?

References

function return value with recur doesn't work properly

Example:

(def f (sci/eval-string "(fn [coll n] (if (zero? n) (first coll) (recur (rest coll) (dec n))))" {:deny '[nth]}))

(f '(1 2 3) 1)
((2 3) 0)

Workaround: use a name and use the name instead of recur.

Possible solution: maybe it's possible to do the recur check inside the function body?

migrate parser to edamame

The edamame library has been extracted from sci, but every time a fix gets applied to edamame we have to apply it here too. It would be better to just use edamame as a library.

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.