Comments (5)
I don't think it's bad for (gensym)
to generate new atoms, as it's a compile-time thing. But that being said, I remember that Core's inliner uses integers for the variables it emits, maybe you could do that too.
from lfe.
Some comments about symbols and atoms.
Two of the goals I have for LFE is to make it as efficient as erlang and to make it completely compatible with erlang and OTP. These goals interact with each other. One result of this is that LFE can never be a CL or a scheme, there are too many properties of erlang which make this impossible, for example immutable data, its module system and handling of function arguments. And its data types.
To keep the homoiconicity of lisp I had to use the erlang datatypes directly and the closest to a CL symbol is the atom. It is different in that it has no value (except itself), function binding or properties and atoms are always interned in the atom table. This also means that it is impossible to make a unique atom, and that you can fill the atom table with "temporary" atoms and crash the systems. The macro expander reuses the same names for generated variables each time.
That's why I haven't implemented (gensym). Also it is not that critical in LFE as variables are scoped and there is no setq, or setf. You can reuse the same temporary variables and the worst that can happen is shadowing.
A possible solution would be for the compiler to allow some structure to represent temporary variables. This would be easy to implement but not safe but with this limitation it could give us hygenic macros.
It would not be possible to use integers as variables as the macro expanding is done in lisp while the Core comes after the code has been compiled. And Core variables are tagged structures.
from lfe.
(gensym) is not just about mutable variables, it's also about in-order execution of expressions and the multiple evaluation of expressions.
Consider the following:
%% Forgive me if this is not the exact LFE syntax, I hope the idea shines through.
(defmacro error-ok (expr)
`(case ((lambda () ,@expr))
(tuple ok value
(ok value))
(tuple error value
(error value))))
What would happen here if value
was already in-scope? You would pattern match against that value, thus meaning that you cannot introduce any lexical variables with macros.
The above is caused by macros expanding into the body of a form.
One way around this in typical Lisps (other than gensym!) is to evaluate the expressions inside a lambda and pass in the expression, but since LFE is Erlang and it pattern matches, the lambda expression will be a lexical closure and it'll pattern match against variables, rather than bringing in a new lexical binding, afaict.
from lfe.
It is not quite that bad. LFE does share erlang's lack of variable scoping so the case creates a new scope and variables in the patterns are new local variables in side the case clauses. So the variable value will be a new variable in each clause which will be the one referred in their body.
This means that you explicitly have to add an explicit equality guard test when you do want to test against an existing. Also multiple occurrence of a variable in a pattern is illegal and you have to use different names with an explicit equality test.
from lfe.
I'm bumping this in order to clarify and update the current LFE documentation to get it ready for the release.
@rvirding, @AeroNotix any final words on this?
from lfe.
Related Issues (20)
- == macro expansion is incorrect HOT 1
- Record accessors in guards don't work HOT 3
- Feature Request: Github Discussions HOT 1
- Run tests without rebar3 HOT 4
- Add make targets for testing HOT 1
- README: Run tests with Makefile HOT 3
- Improve workflow for publishing LFE to hex.pm
- Odd recursion bug with rebar3_lfe as a plugin dep HOT 1
- v2.1.1 tagged but not marked as latest HOT 5
- lc/2 not defined HOT 8
- ets-ms is attempting to match 'undefined' when using match-record with unspecified slots HOT 5
- Error expanding (seemingly valid) qlc macro HOT 12
- Extend documentation for patterns HOT 2
- CI/CD no longer runs on older builds HOT 4
- Type definitions and specifications do not accept empty list syntax HOT 1
- Issues with LFE and Erlang 26.0 (user:start) HOT 5
- Make banner functions public for re-use in rebar3_lfe
- Consider using Erlang's shell:start_interactive for 26+ HOT 1
- Explore the possibility of making the LFE REPL developer experience more configurable HOT 2
- module-alias is ignored for macros HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lfe.