Git Product home page Git Product logo

lfe's Introduction

LFE

Build Status Hex.pm version Hex.pm downloads Hex.pm weekly downloads Hex.pm daily downloads

LFE, Lisp Flavoured Erlang, is a lisp syntax front-end to the Erlang compiler. Code produced with it is compatible with "normal" Erlang code. An LFE evaluator and shell is also included.

Building

To compile LFE, simple clone it and compile:

$ git clone https://github.com/lfe/lfe.git
$ cd lfe
$ make compile

LFE requires Erlang be installed on the system and that the erl binary is in $PATH.

Running the Tests

To run the full suite of tests for LFE, simply use the following:

make tests

Installation

Should you wish to have LFE available system-wide, you can run the following make target:

$ make install

By default this will create the programs lfe, lfec, lfedoc and lfescript in /usr/local/bin. This can be changed by defining the make variable PREFIX to point to the desired parent directory.

Note that the install target will also install the LFE man pages in the appropriate $(PREFIX)/share/man/man* directories. This can be changed by defining the make variable MANINSTDIR to point to the desired top man directory.

So:

$ make install PREFIX=/Users/rv/ MANINSTDIR=/Users/rv/man

will put the programs in /Users/rv/bin and the man pages in the /Users/rv/man/man* directories.

REPL

If you're running LFE from a git clone working dir, you can start the REPL like so after compiling:

$ ./bin/lfe
Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit] [dtrace]

   ..-~.~_~---..
  (      \\     )    |   A Lisp-2+ on the Erlang VM
  |`-.._/_\\_.-':    |   Type (help) for usage info.
  |         g |_ \   |
  |        n    | |  |   Docs: http://docs.lfe.io/
  |       a    / /   |   Source: http://github.com/lfe/lfe
   \     l    |_/    |
    \   r     /      |   LFE v2.1.4 (abort with ^G)
     `-E___.-'

lfe>

If you have installed LFE, then you may start the REPL from any location:

$ lfe

Likewise, you may run an LFE shell script in the same style as shell scripts with:

$ ./bin/lfe script-name script-arg-1 ...

or

$ lfe script-name script-arg-1 ...

Usage

The docs site has several places to explore that will show you how to start using LFE. However, here's a quick taste:

  • start up an LFE REPL as demonstrated above
  • then, do something like this:
lfe> (* 2 (+ 1 2 3 4 5 6))
42
lfe> (* 2 (lists:foldl #'+/2 0 (lists:seq 1 6)))
42

Docker Support

LFE now supports Docker. To get started, simply do the following, once you have Docker set up on your machine:

$ docker pull lfex/lfe

Alternatively, you could build the image yourself:

$ cd lfe
$ docker build .

To bring up the LFE REPL:

$ docker run -it lfex/lfe

Documentation

Files with more technical details:

If you would like to make changes to the LFE documentation and then regenerate the docs, you'll want to read the instructions here:

Join the Community

LFE on Slack, join by requesting an invite here

LFE Forum - Erlang Forums

Maintainers

Cutting Releases

Steps:

  1. Update the version in src/lfe.app.src
  2. Create the release tags
  3. Create a release on Github
  4. Publish to hex.pm

Once the app.src has been updated with the version for the release, you can create and push the tags (to Github) with the following:

make tags

That will create the number-only version as well as the "v"-prefixed version.

For now, the process of creating a release on Github is manual:

  1. Go to https://github.com/lfe/lfe/releases
  2. Click "Draft new release"
  3. Select the correct tag from the drop-down "Choose a tag"
  4. Click "Generate release notes"
  5. Click "Publish release"

Lastly, to publish LFE to hex.pm, you need to have rebar3 installed on our system and an entry for the hex plugin in your system rebar.config file. With that in place, publish a new release to hex.pm requires only the following:

make hex-publish

lfe's People

Contributors

arpunk avatar beji avatar carlomarx avatar chenrui333 avatar hdurer avatar ilovezfs avatar jackdrogon avatar jgarte avatar klaustrainer avatar m-doughty avatar mankykitty avatar mattsta avatar maximvl avatar mdbergmann avatar mopemope avatar nobukazuhanada avatar norton avatar oubiwann avatar pierre-rouleau avatar profitware avatar purcell avatar redpine50 avatar rvirding avatar skovsgaard avatar stevenproctor avatar wardbekker avatar xgqt avatar yastanotheruser avatar yurrriq avatar zkessin 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

lfe's Issues

rebar

which version of rebar is needed to install? It seems that my version of rebar does't manage install. compiling seems to work fine.

$ make install
if which -s rebar;
then rebar install;
elif [ "$ERL_LIBS" != "" ];
then mkdir -p /lfe/ebin ;
cp -pPR ebin /lfe;
cp -pPR emacs /lfe;
else exit 1;
fi
Command 'install' not understood
make: *** [install] Error 1

$ erl --version
Erlang R14A (erts-5.8) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Erlang distribution

Hello,

any chance to see LFE integrated in the main Erlang distribution?

Thanks.

Invalid numerical bases allowed

Hey Robert,

Just wanted to add this to the queue somewhere ;-) You'd mentioned it in an email back in January (on the mail list), and I just came across it today when checking my work for the LFE docs.

In Erlang:

4> 36#37.
115
5> 37#37.
* 1: illegal base '37'
5> #37.
* 1: syntax error before: 37
5>

In LFE:

> #36r37
115
> #37r37
118
>

I'm assuming an error should be raised there, since the value of the base is outside the range of 2-36.

The lower end of the spectrum looks good, though:

> #1r37
exception exit: #(error #(1 lfe_scan #(user "illegal based number")) 1)
  in (lfe_io scan_and_parse 3)

Installing LFE

Installing LFE has now been changed so that the LFE directory tree is not moved but symbolic links to the 3 LFE start commands, lfe, lfec and lfescript, are created. By default they are created in the same directory as the 'erl' command, or if this can't be found then in "/usr/local/bin". This can be changed by setting the make variable DESTBINDIR when doing make install.

This is still experimental but seems to be the right thing.

pattern matching in function head doesn't work for lambdas

Pattern matching in the head of a named function works fine both in compiled and interpreted mode. However, it doesn't work for lambdas (compiled and interpreted).

This one works fine:

(defmodule foo (export (a_and_c 1)))
(defun a_and_c ([(tuple a b c)] (tuple a c)))
(a_and_c (tuple 'a 'b 'c)) ; returns #(a c)

But that one does not work at all:

(defmodule bar (export (a_and_b 1)))
(defun a_and_b (t)
  (let ((issue_7 (lambda ([(tuple a b c)] (tuple a b)))))
    (funcall issue_7 t)))

When slurping the function, everything looks alright, but when it is invoked, a badarity error occurs:

(a_and_b (tuple 'a 'b 'c)) ; should return `#(a b)`, but does not
exception error: #(badarity #(#Fun<lfe_eval.15.56600010> (#(a b c))))

Instead of the correct arity of one (like it applies to the named function), the lambda function has an incorrect arity of 2:

(: lists keyfind 'arity 1 (: erlang fun_info (fun a_and_b 1))))) ; returns #(arity 2)

Compiling it does not work, too:

(: lfe_comp file '"/tmp/bar.lfe")
/tmp/bar.lfe:2: bad form: lambda
error

The installation guide when not using lfetool is wrong

The instructions for installing LFE when not using lfetool are wrong. It is no longer necessary to put the LFE directory in the code path as installing now just add links for lfe, lfec and escript programs to a bin directory, default /usr/local/bin. These point into the LFE directory and the code path is automatically fixed.

bracketable comments with #| ... |#

Hi,

It would be useful to have #| and |# enclose text that is to be treated as a comment. This saves having to place a semicolon in front of every line of the area intended to be commented. Useful for both genuine comments and for rapidly "commenting out" stretches of code.

It may also help to make #|...|# nestable.

Precedent: Common Lisp and Racket (where they are nestable too).

Thanks,

--dorai

"make clean" deletes ./lfe

In both master and develop, whenever I perform make clean the ./lfe file is deleted. Not sure what's going on with that; trying to troubleshoot it now.

Note that I did not witness this behaviour prior to installing rebar...

Tags

Would it be better if the tags did not have a 'v' prefix? If they were just '0.9'?

Fix up README

The README could benefit from some more organization, maybe some more info, and a quick usage (and installation via rebar dep). Also, I'd like to move the version history to its own file...

Functions can't reuturn just an unquoted string

I'm I'm guessing correctly, the following code doesn't work right now due to the manner in which docstring parsing is currently implemented:

(defun my-const () "some string constant")

Instead, if must be quoted:

(defun my-const () '"some string constant")

It would be nice if we could return a simple string in this case, to maintain symmetry with how strings are now handled in the rest of LFE (or rather, how LFE allows them to be written).

Create branch for record-fields macro

This macro is done; just need to test it against some mnesia code that's creating a table. When that's done, I'll push the branch, add an example, and submit a pull request.

Compile fail on Raspberry Pi Raspbian Wheezy

I get a compile fail on Raspberry Pi:

Compiling src/lfe_comp.erl failed:
src/lfe_comp.erl:30: can't find include lib "compiler/src/core_parse.hrl"
ERROR: compile failed while processing /home/pi/downloads/lfe: rebar_abort
make: *** [compile] Error 1

This looks to me like either I have not set up environment correctly or the erlang/otp install is a binary only for Pi so erlang sources are not included.

In either event, has someone sorted getting lfe running on pi?

Cheers,
B

let vs let*

Is there any reason to have let over let* nowadays?

Personally, having let* be let and remove having two would be better overall? Less cognitive overhead.

Improving handling of guards

The LFE compiler handles guards correctly but not as efficiently as possible. One reason is that optimisation passes in the erlang compiler assume that things look exactly like they do from the erlang compiler otherwise they can sometimes do something wrong or even crash. For this reason I have turned off some optimisation passes.

What I plan to do now is rewrite some of the LFE compiler code generation pass to output more erlang compiler like code so I can, hopefully, turn on the optimisation again.

`flet` does not work in interpreter

In contrast to let, flet does not work in the interpreter.

This one prints "Hello!" as expected:

(let ((hello (lambda () (: io format '"Hello!")))) 
    (funcall hello)) ; prints "Hello!" as expected

Whereas that one results in a badarg error:

(flet ((hello (lambda () (: io format '"Hello!")))) 
    (hello)) ; wrongly generates a badarg error
exception error: badarg
  in (: erlang length lambda)
  in (lfe_eval -eval_let_function/2-fun-0- 3)
  in (lists foldl 3)

Possible issue with string quoting

I just ran across an issue where there is different behaviour for quoted and non-quoted strings.

This function returns the expected result:

> (defun string-1 () '"hello!")
string-1
> (string-1)
"hello!"

However, with no quoted string, this doesn't work:

> (defun string-2 () "hello!")
string-2
> (string-2)
()

Compile on versions less than 17.0 failing

Here's the output when attempting to compile LFE on R15 and R16 (using rebar):

==> lfe (compile)
Compiled src/lfe_scan.xrl
Compiled src/lfe_qlc.erl
Compiled src/lfe_init.erl
Compiled src/lfescript.erl
Compiled src/lfe_bits.erl
Compiling /home/travis/build/lfex/lfest/deps/lfe/src/lfe_parse.erl failed:
/home/travis/build/lfex/lfest/deps/lfe/src/lfe_parse.erl:122: illegal guard expression
ERROR: compile failed while processing /home/travis/build/lfex/lfest/deps/lfe: rebar_abort
make: *** [compile] Error 1

This can be seen here, in this Travis CI build attempt:

I also get another error on some projects:

==> lfe (compile)
Compiled src/lfe_scan.xrl
Compiled src/lfe_qlc.erl
Compiling /home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl failed:
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:856: function is_map/1 undefined
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:121: Warning: variable 'M' shadowed in 'fun'
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:125: Warning: variable 'M' shadowed in 'fun'
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:478: Warning: function init_letrec_env/1 is unused
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:484: Warning: function extend_letrec_env/3 is unused
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:484: Warning: variable 'Fbs0' is unused
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:753: Warning: variable 'M' shadowed in 'fun'
/home/travis/build/lfex/exemplar/deps/lfe/src/lfe_eval.erl:757: Warning: variable 'M' shadowed in 'fun'
ERROR: compile failed while processing /home/travis/build/lfex/exemplar/deps/lfe: rebar_abort
make: *** [compile] Error 1

This can be see in this Travis CI build attempt:

lfe doesn't install bin/*

lfe doesn't install any binaries, only libs. It should probably install them in code:root_dir() ++ "bin" by default ...

Two people have emailed/msg'ed on IRC about this in the past few days; probably a good idea to fix. If no one else jumps on this in the next day or so, I can easily knock it out...

Faulty handling of environment in shell

When running shell scripts in the LFE shell the handling of the environment is not correct and sometimes variables and functions aren't accessed as they should.

Please refork develop

I made a mess of the develop branch and ended up having to force push a new one. It is only relevant for the very latest entries but those who have forked it should refork or repull it to get in phase.

Sorry about that.

LFE and hygenic macros?

Hi,

After an interesting talk with @rvirding in #erlang, it's clear that LFE does not have the utilities to create hygenic macros.

Take the following situation (Common Lisp):

(defmacro for (var start stop &body body)
 `(progn
    (format t "stopping at: ~d" ,stop)
    (do
    ((,var ,start (1+, var)))
    ((> ,var ,stop))
    ,@body)))

This works fine when we call it as such:

(for i 1 5
  (print i))
;;
stopping at: 5
1 
2 
3 
4 
5 
NIL

However, calling this macro with a call to another side-effecting function yields strange results:

CL-USER> (for i 1 (random 10) (print i))
stopping at: 9
1 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 3
1 
2 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 7
1 
2 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 1
1 
2 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 8
1 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 7
1 
2 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 5
1 
2 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 2
1 
2 
3 
4 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 0
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 2
1 
2 
3 
4 
5 

Which is most definitely incorrect.

Ok, so how about we bind the stop call before making the do block? Okay!

(defmacro for (var start stop &body body)
 `(let ((real-stop ,stop))
    (progn
      (format t "stopping at: ~d" real-stop)
      (do
       ((,var ,start (1+, var)))
       ((> ,var real-stop))
        ,@body))))

Yields:

CL-USER> (for i 1 (random 10) (print i))
stopping at: 6
1 
2 
3 
4 
5 
6 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 3
1 
2 
3 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 2
1 
2 
NIL
CL-USER> (for i 1 (random 10) (print i))
stopping at: 9
1 
2 
3 
4 
5 
6 
7 
8 
9 
NIL

Which is what we want! But wait...

What if the body of the macro was used as such:

(for i 1 (random 10) (setq real-stop :banana))

Yields (SBCL):

The value :BANANA is not of type REAL.
   [Condition of type TYPE-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [ABORT] Abort thread (#<THREAD "repl-thread" RUNNING {10036D8063}>)

Backtrace:
  0: ((LAMBDA ()))
  1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FOR I 1 (RANDOM 10) (SETQ REAL-STOP :BANANA)) #<NULL-LEXENV>)
  2: (EVAL (FOR I 1 (RANDOM 10) (SETQ REAL-STOP :BANANA)))
 --more--

Whoooops.

What about the wholly more insidious:

(for i 1 (random 10) (setq real-stop (random 100000)))

Which means the iteration stops on a random basis entirely.

Lisps get around this usually by using a call to (gensym) which creates a symbol which is guaranteed to be unique, this means we can bind forms to a generated symbol thereby ensuring that the form is evaluated once and that the symbol will not clash with any captured body.

@rvirding mentioned to me that (gensym) would create atoms in the atom table. Number one, I do not understand fully how LFE is implemented. However, I don't understand why atoms are needed in the creation of a Variable label? You would just need to generate a variable name which can be used in the body.

Am I missing some information here?

(lc ...) not working with (when ...)

There is an example of a list comprehension in the user guide:

(lc ((<- v l1) (when (> v 5))
     (== (rem v 2) 0))
  v)

When attempting this in the REPL on v0.8 and v0.9, this is what I get:

> (set l1 '(1 2 3 4 5 6 7 8 9))
(1 2 3 4 5 6 7 8 9)
> (lc ((<- v l1) (when (> v 5))
     (== (rem v 2) 0))
    v)
exception error: #(unbound_func #(when 1))

Is this a bug? Or am I doing something wrong?

lfe fails to run when passed name

The following commands cause LFE to fail with an infinite loop:

./bin/lfe -pa ./ebin -name erl_node@cahwsx01
./bin/lfe -pa ./ebin -sname erl_node@cahwsx01

The resulting looping error looks like this:

...
(erl_node@cahwsx01)> exception error: badarg
  in (: io put_chars <0.31.0> unicode ok)

(erl_node@cahwsx01)> exception error: badarg
  in (: io put_chars <0.31.0> unicode ok)

(erl_node@cahwsx01)> exception error: badarg
  in (: io put_chars <0.31.0> unicode ok)

(erl_node@cahwsx01)> exception error: badarg
  in (: io put_chars <0.31.0> unicode ok)
...

Support user customisation of LFE via options

I'd like to add support for user customisations of LFE via rebar.config

Proposal:

  • Add support for a new top-level rebar.config entry: {lfe, [...]}
    • [...] would be a proplist
    • tuples in the list may be added by users or applications but should avoid conflicts with LFE by putting their data in something link {lfe, [... {'app-or-lib', [...]} ...}

Initial use case:

  • overriding LFE shell prompt
  • overriding LFE shell abort command message
  • overriding LFE shell banner

Example demonstrating the above use cases:

{lfe, [
    {prompt, "LFE> "},
    {shell_abort_msg, "YUNO LOVE ME?!"},
    {banner_file, "/home/alice/.lfe/my-lfe-banner.txt"},
    {show_banner, true},
    {first_files, [...]}
]}.

Can't use Erlang Unit Test framework macros in LFE

We ran into this problem a while ago, but I can't seem to find the thread. I thought there was a ticket open for it, but I guess not?

I thought we'd seen this when trying to include libs in LFE...

Robert, I think at one point you said you had an idea for fixing it? (so maybe it's working now?)

escript-like functionality?

Currently, when I want to run some LFE code as a script, I need to do something like the following:

erl -pa ./ebin/  -noshell \
  -s lfe_comp file tmp/arith \
  -s arith demo-arith \
  -s erlang halt

However, this has the side effect of generating a .beam file... which is not desirable for scripting. escript loads files without compiling; how could we do something similar?

Ideally, we would have lfescript, but short of that, it would be create to do something like the following:

erl -pa ./ebin/  -noshell \
  -s lfe_shell slurp tmp/arith \
  -s arith demo-arith \
  -s erlang halt

What do you think?

lfec keeps non-files in file list args

When running lfec with the output dir argument, I got these odd errors:

./-o.lfe:none: no such file or directory
<some path>.lfe:none: no such file or directory

When I debugged this in lfec, it turned out that when the file list is provided, the -o and <outputdir> are included in it.

I was going to mess with the pattern matching in the parse-opts function, but then it occurred to me that even with that, someone (or more likely someone's script) might still pass a file that didn't exist. As such, it seemed that a general filter might be a better approach (2 bids, one stone).

I'll submit the PR for this shortly.

can not run the interpreter after successful compiling

0: ~/sexp/lfe/git/rvirding-lfe/bin
$ ./lfe
{error_logger,{{2014,11,23},{13,59,48}},crash_report,[[{initial_call,{supervisor_bridge,user_sup,['Argument__1']}},{pid,<0.23.0>},{registered_name,[]},{error_info,{exit,{undef,[{lfe_init,start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},{line,99}]},{user_sup,init,1,[{file,"user_sup.erl"},{line,48}]},{supervisor_bridge,init,1,[{file,"supervisor_bridge.erl"},{line,79}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]},[{gen_server,init_it,6,[{file,"gen_server.erl"},{line,330}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}},{ancestors,[kernel_sup,<0.10.0>]},{messages,[]},{links,[<0.11.0>]},{dictionary,[]},{trap_exit,true},{status,running},{heap_size,610},{stack_size,27},{reductions,145}],[]]}
{error_logger,{{2014,11,23},{13,59,48}},supervisor_report,[{supervisor,{local,kernel_sup}},{errorContext,start_error},{reason,{undef,[{lfe_init,start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},{line,99}]},{user_sup,init,1,[{file,"user_sup.erl"},{line,48}]},{supervisor_bridge,init,1,[{file,"supervisor_bridge.erl"},{line,79}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}},{offender,[{pid,undefined},{name,user},{mfargs,{user_sup,start,[]}},{restart_type,temporary},{shutdown,2000},{child_type,supervisor}]}]}
{error_logger,{{2014,11,23},{13,59,48}},crash_report,[[{initial_call,{application_master,init,['Argument__1','Argument__2','Argument__3','Argument__4']}},{pid,<0.9.0>},{registered_name,[]},{error_info,{exit,{{shutdown,{failed_to_start_child,user,{undef,[{lfe_init,start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},{line,99}]},{user_sup,init,1,[{file,"user_sup.erl"},{line,48}]},{supervisor_bridge,init,1,[{file,"supervisor_bridge.erl"},{line,79}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}}},{kernel,start,[normal,[]]}},[{application_master,init,4,[{file,"application_master.erl"},{line,133}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}},{ancestors,[<0.8.0>]},{messages,[{'EXIT',<0.10.0>,normal}]},{links,[<0.8.0>,<0.7.0>]},{dictionary,[]},{trap_exit,true},{status,running},{heap_size,610},{stack_size,27},{reductions,147}],[]]}
{error_logger,{{2014,11,23},{13,59,48}},std_info,[{application,kernel},{exited,{{shutdown,{failed_to_start_child,user,{undef,[{lfe_init,start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},{line,99}]},{user_sup,init,1,[{file,"user_sup.erl"},{line,48}]},{supervisor_bridge,init,1,[{file,"supervisor_bridge.erl"},{line,79}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}}},{kernel,start,[normal,[]]}}},{type,permanent}]}
{"Kernel pid terminated",application_controller,"{application_start_failure,kernel,{{shutdown,{failed_to_start_child,user,{undef,[{lfe_init,start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},{line,99}]},{user_sup,init,1,[{file,"user_sup.erl"},{line,48}]},{supervisor_bridge,init,1,[{file,"supervisor_bridge.erl"},{line,79}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}}},{kernel,start,[normal,[]]}}}"}

Crash dump was written to: erl_crash.dump
Kernel pid terminated (application_controller) ({application_start_failure,kernel,{{shutdown,{failed_to_start_child,user,{undef,[{lfe_init,start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},

Quickstart problem

Hi, I try to run LFE REPL according to this manual http://lfe.github.io/quick-start/3.html, but I receive this message all the time

In order to run the LFE REPL from this script, it has to
be executed in its uncompressed form. For your convenience,
the script has just been uncompressed. Please re-execute
the same command to start the REPL.

Can you help me? Erlang 17.0

Blank docstrings are not allowed. Can haz?

Sometimes I like to sub-out docstrings in functions like so:

(defun func-1 ()
  ""
 (do (some stuff)))

(defun func-2 ()
  ""
 (do (some (more stuff))))

(defun func-3 ()
  ""
 (do less))

And as things shape up, go back and fill these in. Right now, LFE doesn't support empty docstrings.

Change interface to lfe_io:read and add lfe_io:read_string

lfe_io:read currently returns the sepxr or generates an error. It would be better to return tagged returns and not generate an error as this is more standard for input functions and is what the other input functions in lfe_io do.

lfe_io:read([IoDevice]) -> {ok,Sexpr} | {error,Error}.

Also add the function lfe_io:read_string to read a string.

Support for R15B03?

I'm very interested in playing with this, but 1) am very inexperienced with Erlang, and 2) only have R15B03 installed on my system (Mac OS X 10.8.2; Erlang installed via brew). Any chance to support it?

When attempting to execute ./lfe, I get the following:

{"init terminating in do_boot", {undef,
  [{lfe_boot,start,[],[]},{init,start_it,1,[]},{init,start_em,1,[]}]}}

Crash dump was written to: erl_crash.dump
init terminating in do_boot () 

Compiler accepts raw data in types which are illegal to the backend erlang compiler

The backend erlang compiler only accepts data with literal constructs, for example atoms, tuples and list, but does not accept other data types as raw input. So an pid can not occur in the code. This is never explicitly checked as the abstract data cannot represent them. In LFE, however, the input is just raw s-exprs which can in principle include anything and doing this will crash the compiler.

Fix R12B->R13B Incompatibility Quickfix

From the README:

A quick fix has been added to compensate for some incompatibilites in
Core Erlang between the old R12B and the new R13B. The fixes are found
in the file lfe_codegen.erl. For one fix code must be chosen depending
on whether the systems runs on R12B or R13B, this is the (tiny)
function c_fname/3 near the end of the file. Choose the right version
of the function. The .beam file in ebin is for R13B.

I will try to make a better fix soon. Sorry about that.

Problem including files from different projects

This was discussed on the following thread:
https://groups.google.com/d/msg/lisp-flavoured-erlang/eJH2m7XK0dM/WFibzgrqP1AJ

Robert summarized his views with the following:

I think the real problem is that currently include and include-lib have no concept of a include path and only look relative to current directory for include and in the library Erlang dirs for include-lib. Though include-lib does know about ERL_LIBS.

A better solution would be introduce the concept of an include path. In conjunction with this whether to keep include/include-lib as macros or make them top-level forms which are interpreted at the same time as macros. Whcih is really almost the same.

I will think some more about this.

LFE command to read commands from string

There has been a request to be able to read shell commands from a string as well as from a script file or from the standard input. My suggestion is to "steal" the erl -eval flag for this. Command line args following this would become the script name and script args. So

lfe -eval "<commands>" script-name arg1 arg2 ...

would read commands from the string and the shell variables script-name and script-args would be bound as when normally running a script. The -eval flag would automatically terminate the flags and a terminating -- would not be necessary though it would be handled sensibly.

One question is whether the value of the last command should be printed by default. I don't think so as there are short shell commands p and pp which can be called to do this.

Simple idea for a first iteration of an LFE stdlb

For context, see parent task, #107.

In LFE:

  • Create a lib or stdlib directory in the LFE code base
  • Add a README to explain what it does
  • Add a Makefile so that the appropriate top-level LFE make targets can cd and compile the libraries
  • In the stdlib Makefile, add a variable that will hold a list of the set of libraries that will comprise the stdlib
  • In the stdlib Makefile, add a target for downloading LFE libraries for the stdlib
  • In the stdlib Makefile, add a target for compiling LFE libraries for the stdlib
  • Compile all libs to the LFE ebin dir
  • Copy the libs' include files to LFE include dir
  • Add a new top-level make target for LFE (e.g., make stdlib) that will build the defined libraries

In the "lfe" Github org:

  • Copy some libraries (wholesale or in part) to the "lfe" org on github
  • Prefix these repo names with "stdlib-" (self-documenting, for purposes of clarity)
  • Pare down these repos so simply include (1) a README (which will eventually contain or link to complete documentation for the library), (2) a src dir containing LFE modues, and (3) an optional include dir containing macros, functions, records, etc.

For both:

  • Step through a standard LFE build, and make sure everything works
  • Iron out bugs or issues with the make stdlib target
  • Ensure that the standard LFE build still works
  • Ask @rvirding to give it a whirl :-)

named let

Hi,

(This is an elucidation of what I was unable to describe within twitter's message length.)

In languages where loops can only be obtained by tail-recursive procedure calls -- e.g., Scheme and LFE, but not Common Lisp --, it is useful to have a named-LET macro. Unfortunately, Scheme muddies the issue a bit by using the same name LET for both regular LET and named-LET, distinguishing them based on whether or not a symbol occurs immediately after the LET. I'll call it NLET to avoid confusion.

(NLET name ((x v) ...) e ...) 

should expand to (in LFE, which is a LIsp-2)

(fletrec ((name (x ...)
                e ...))
   (name v ...))

Sample use:

(nlet loop ((n 1)
  (if (=< n 10)
      (progn
         (: io format '"~p~n" (list n))
         (loop (+ n 1))))

which prints the integers from 1 through 10.

The choice of name for this syntax is not important, nor does LET need to be "overloaded" as in Scheme. There is a precedent in older Schemes for using a distinctive name for it, viz., RECUR in older Chez Scheme.

The suggestion here is to add NLET (under whatever name) to LFE. It is very convenient for writing loops in properly tail-rec languages, because the initialization is easy to read, unlike when writing out the loop using (F)LETREC, which is both longer and puts the initialization at the end. E.g., the same loop described above, using only FLETREC, would be:

(fletrec ((loop (n) 
               (if (=< n 10)
                   (progn
                      (: io format '"~p~n" (list n))
                      (loop (+ n 1))))))
   (loop 1))

thanks,
--dorai

Add support for (describe ...) in the REPL

So, I know that when we talked about adding support for docstrings, we agreed to simply discard the docstring data. In fact, I advised that, iirc ;-)

Now that our REPL is getting much cooler, I was hoping we could add support for (describe ...) :-)

Questions, of course, would be things like these:

  • where do we store docstrings?
  • how do we treat Erlang-style docs? (e.g., what happens when we (describe #'lists:map/2)?
  • what about parsing docstings for edoc markup?

Add support for Docker

The following needs to be done to be recognized as an official Docker repo

  • Add Dockerfile to LFE
    • Test build of LFE Dockerfile
    • Run an app with the Dockerfile, confirm/document usage
    • Run a script with the Dockerfile, confirm/document usage
  • Create a new LFE tag/release that has the Dockerfile in it
  • Submit a PR adding LFE to docker-library/official-images
  • Submit a PR adding LFE to docker-library/docs

Work for this is going in this branch:

LFE's having a hard time including lager.hrl

Here's the error in the REPL:

> (include-file "deps/lager/include/lager.hrl")
1: Warning: unable to translate macro 'INT_LOG'
exception error: #(unbound_func #(extend-module 1))

Something similar happens when I try to include it in a file and then compile. In the code:

(include-file "deps/lager/include/lager.hrl")

And the compile output:

Compiled src/sample-app-routes.lfe
Compiled src/sample-app-nav.lfe
src/sample-app-gae.lfe:5: Warning: unable to translate macro 'INT_LOG'
Compiled src/sample-app-gae.lfe
Compiled src/sample-app-content.lfe

Here's a copy of the hrl file.

Store function docstrings

In order to keep building the LFE REPL up as a first-class development tool, we're going to need so support displaying function docstrings (per issue #67). One of the first things that needs to be done for that, though, is to store the docstrings somewhere.

I'm not sure if there is some place to store metadata in compiled functions, but if that's not possible, we could add a module-level attribute "docstrings" with a proplist of #(func-name func-docstring) pairs ...

CL-Style Comment Support

Hopefully I'll get this request in there before the merge to master :-)

What do you think the chances are of adding Common Lisp-style comments to LFE are? By which I mean this:

    (defun something-cool (arg1, arg2)
      "Here is a long docstring
       that totally says what this 
       crazy function does..."
      ...)

After Erlang Factory in SF, you mentioned that this should probably be fairly easy? Since the compiler wouldn't need to do anything with it, other than drop it...

What do you think?

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.