Skip to content

Commit

Permalink
Added at-consts macro (#133)
Browse files Browse the repository at this point in the history
Fixes #111

Also removed references to Julia 0.6 and 0.7 in the Readme & docs.
  • Loading branch information
mauro3 authored Jan 22, 2021
1 parent 4b917d2 commit 74e392e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 8 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 2021-01-22
Added `@consts` macro to define a block of constants.

# 2019-09-10
Added support of packing immutables (by creating one) through `@pack_SomeType`.

Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ julia> MyNT(x = 2)
(x = 2, y = "foo", z = :bar)
```
> v0.6 users: since `NamedTuples` are not supported in base Julia v0.6, you must import the `NamedTuples.jl` package. Be aware of [this issue](https://github.com/JuliaLang/julia/issues/17240) with keyword arguments in v0.6.
Unpacking is done with `@unpack` (`@pack!` is similar):
```julia
struct B
Expand All @@ -77,6 +75,16 @@ a = BB.a
c = BB.c
```
Defining several constants
```julia
@consts begin
a = 1
b = 2.0
c = "a"
end
```
The features are:
- a keyword constructor for the type
Expand All @@ -88,7 +96,8 @@ The features are:
- packing and unpacking macros for the type: `@unpack_*` where `*` is
the type name.
- generic packing and unpacking macros `@pack!`, `@unpack` (work with
any types).
any types, via [UnPack.jl](https://github.com/mauro3/UnPack.jl))
- `@consts` macro to defined a bunch of constants
The keyword-constructor and default-values functionality will probably
make it into Julia
Expand Down
17 changes: 13 additions & 4 deletions docs/src/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,6 @@ re-definition warnings, then use [`@with_kw_noshow`](@ref).

As mentioned in the README, the `@with_kw` macro can be used to decorate a named tuple and produce a named tuple constructor with those defaults.

> Users of Julia v0.6 should be aware of this [caveat](https://github.com/JuliaLang/julia/issues/17240) that prohibits assignments like `@with_kw (f = f, x = x)`. This is a consequence of different scoping rules for keyword arguments in [v0.6](https://docs.julialang.org/en/stable/manual/functions/#Evaluation-Scope-of-Default-Values-1) and [v0.7](https://docs.julialang.org/en/latest/manual/functions/#Evaluation-Scope-of-Default-Values-1).
> Users of v0.6 will also need to explicitly import `NamedTuples.jl`, since this functionality is not present in that version of base Julia.
These named tuples can be defined as such:

```julia
Expand Down Expand Up @@ -178,6 +174,19 @@ julia> z
Since the macro operates on a single tuple expression (as opposed to a tuple of assignment expressions),writing `@with_kw(x = 1, y = :foo)` will return an error suggesting you write `@with_kw (x = 1, y = :foo)`.
# Blocks of constants
Several constants can be defined like so:
```julia
@consts begin
a = 1
b = 2
c = 3
end
```
(if you do the math, you'll need more than three constants in the block to actually save typing.)
# (Un)pack macros
## `@unpack` and `@pack` re-exported from UnPack.jl
Expand Down
23 changes: 22 additions & 1 deletion src/Parameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import Base: @__doc__
import OrderedCollections: OrderedDict
using UnPack: @unpack, @pack!

export @with_kw, @with_kw_noshow, type2dict, reconstruct, @unpack, @pack!, @pack
export @with_kw, @with_kw_noshow, type2dict, reconstruct, @unpack, @pack!, @pack, @consts

## Parser helpers
#################
Expand Down Expand Up @@ -657,4 +657,25 @@ macro with_kw_noshow(typedef)
return esc(with_kw(typedef, __module__, false))
end

###########
# @consts macro

"""
"""
macro consts(block)
@assert block.head == :block
args = block.args
for i in eachindex(args)
a = args[i]
if a isa LineNumberNode
continue
elseif a.head == :(=)
args[i] = Expr(:const, args[i])
else
error("Could not parse block")
end
end
return esc(block)
end
end # module
14 changes: 14 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -668,3 +668,17 @@ z2 = TestModule.test_function(TestModule.TestStruct(; y = 9.0))
@test foo()() == (x = 1, y = 2)
@test foo()(y=4) == (x = 1, y = 4)
end

####
# @consts
####
@consts begin
a34 = 1
b34 = 2.0
d34 = sin(56)
end
@test a34 == 1
@test b34 == 2.0
@test_throws ErrorException global b34 = 1
## this test is dependent on Julia version, leave it:
# @test_warn "WARNING: redefinition of constant b34. This may fail, cause incorrect answers, or produce other errors." global b34 = 4.0

0 comments on commit 74e392e

Please sign in to comment.