Adding to the manual gensym for macros are 2 new
macros, but very literal from the CL in
letoverlambda.
The first is the (with-gensyms ...) macro that
can generate a small set of syms for a macro. Works
something like:
(defmacro adder2 [A B]
(with-gensyms [a b]
`(let [[~a ~A] [~b ~B]]
(+ ~a ~b))))
and ~a and ~b will be replaced with (gensym "a") and
(gensym "b") respectively.
Then the final macro is a new defmacro that will automatically
replace symbols prefaced with "g!" with a new gensym based on the
rest of the symbol. So in this final version of 'nif':
(defmacro/g! nif4 (expr pos zero neg)
`(let [[~g!result ~expr]]
(cond [(pos? ~g!result) ~pos]
[(zero? ~g!result) ~zero]
[(neg? ~g!result) ~neg])))
all uses of ~g!result will be replaced with (gensym "result").
Simple implementation of gensym in Hy.
Returns a new HySymbol.
Usable in macros like:
(defmacro nif [expr pos zero neg]
(let [[g (gensym)]]
`(let [[~g ~expr]]
(cond [(pos? ~g) ~pos]
[(zero? ~g) ~zero]
[(neg? ~g) ~neg]))))
This addresses all the general comments about (gensym), and doesn't
try to implement "auto-gensym" yet. But clearly the macro approach
instead of the pre-processor approach (as described in the
letoverlambda (http://letoverlambda.com/index.cl/guest/chap3.html#sec_5)
is the way to go
The fancypants Hy award goes to Nick for coming up with the quoted
symbol hack for exports. This broke with foo?, since the export string
needs to be is_foo, but using a quoted string will pick up the change
due to it being a Symbol.
Mad clown love for that, @olasd.
A couple of more macros:
hy> (--each-while [1 2 3 4 5] (< it 3) (print it))
1
2
3
hy>
```--each-while``` continues to evaluate the body form while the
predicate form is true for each element in the list.
```--map-when``` uses a predicate form to determine when to apply the
map form upon the element in the list:
hy> (list (--map-when (even? it) (* it 3) [1 2 3 4]))
[1, 6, 3, 12]
Anaphoric macros reduce the need to specify a lambda by binding a
special name in a form passed as a parameter to the macro. This allows
you to write more concise code:
(= (list (--filter (even? it) [1 2 3 4])) [2 4])
This patch just adds a few basic ones. Other forms that can be
converted to anaphoric versions include reduce, remove, enumerate,
etc.
This gets rid of the dichotomy between bootstrap.py and macros.hy,
by making both files hy modules.
I added some error checking to make the macros more resilient. The
biggest (user-visible) change is the change in cond, which now only
accepts lists as arguments. Tests updated accordingly.
Closes: #176 (whoops, no more bootstrap)
This rounds out the first pass at a set of core functions, adding
some that were not in the first PR.
From here I'm working on a contrib.seq and contrib.io module to
hold less obvious but maybe interesting native functions that can
move to core if desired.
This should also close out issure #150 asking for some core
functions like these.
This will let us use (basic) yield from behavior from Python 2. This
isn't complete, and is low-hanging fruit for others willing to hack
on hy.
I've also changed the macrosystem to allow for proper bootstrapping.
This is similar to how it's done elsewhere in the codebase (stdlib
stuff).
Updated most methods to replace While with For, and added tons of new tests
for things like (cycle []) and lists with None's in them.
thanks @olasd
Add set of new core functions
Add set of new core functions to the stdlib.
Moved the auto-import code from compile_expression to
HySymbol so that "even?' in this style expression will
be found and imported.
(list (filter even? [1 2 3 4 5]))
The core functions are documented in 2 sections, one
for basic functions like (even?..) and (nth ...) and
one for all the sequence functions.
Update: This removes all the caching decorators, misnamed as
'lazy-seq' from the core. All sequence methods now just use
yield to return a generator, so they are Python-lazy
Further refinements of core functions
Cleaned up the docs to use 'iterator' instead of 'generator'
Fixed drop to just return the iterator instead of an extra
yield loop. But also added a test to catch dropping too
many.
This adds a class to avoid returning when we have a Yieldable
expression contained in the body of the function. This breaks Python
2.x, and ought to break Python 3.x, but doesn't.
We need this fo' context managers, etc.
This commit also has work from @rwtolbert adding new testcases and
fixes for yielded entries behind a while / for.
Add set of new core functions to the stdlib.
Moved the auto-import code from compile_expression to
HySymbol so that "even?' in this style expression will
be found and imported.
(list (filter even? [1 2 3 4 5]))
The core functions are documented in 2 sections, one
for basic functions like (even?..) and (nth ...) and
one for all the sequence functions.
Update: This removes all the caching decorators, misnamed as
'lazy-seq' from the core. All sequence methods now just use
yield to return a generator, so they are Python-lazy
Further refinements of core functions
Cleaned up the docs to use 'iterator' instead of 'generator'
Fixed drop to just return the iterator instead of an extra
yield loop. But also added a test to catch dropping too
many.
This will let us implement common functions seen in other lisps,
and allow them to be importable, without explicit imports. The goal
is to keep this as small as we can; we don't want too much magic.
I've added `take' and `drop' as examples of what we can do.
A macro is available in the module where it was defined and
in any module that does a require of the defining module.
Only macros defined in hy.core are globally available.
Fixes#181