Skip to content

Self-documentation: refactor enums? #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pygy opened this issue Feb 20, 2013 · 5 comments
Closed

Self-documentation: refactor enums? #11

pygy opened this issue Feb 20, 2013 · 5 comments

Comments

@pygy
Copy link

pygy commented Feb 20, 2013

Pipe dream: it would be nice to have

require("CairoConstants")
CairoConstants.format.rgb24 # -> 1
show(CairoConstants.format) # List all names, alphabetically.

It could be implemented as descendants of an abstract CConst/CEnum type (for the show() implementation), built with a macro that takes a name, an offset and an array of symbols (with nothing for holes) as parameters. A variation could take Dict with symbols as keys.

Once immutable types are implemented, this should be as efficient as traditional const values.

@pygy
Copy link
Author

pygy commented Feb 21, 2013

What do you think of this?

module Cairo

format = @ CEnum [
    -1, :invalid,
    :argb32,
    :rgb24,
    ...
]

@ assert format.argb32 == 0 # true

end

Note that negative and non-incremental indices must come before their names.
Implementation:

abstract CEnum

module Base

function show{T<:CEnum}(io::IO, enum::T)
    for name in sort(map(string,[names(enum)...]))
        print(io, "$name\n")
    end
end

macro CEnum(symbols)
  symbols = eval(symbols)
  typ = symbol(string("CEnum",gensym()))
  names = Any[] # `Any` is required for the `Expr(...)` below
  values = Int[]
  i = isa(symbols[1], Integer) ? symbols[1] : 0
  first = true
  for e in symbols
    if isa (e, Symbol)
      push!(names, e)
      push!(values, i)
      i = i +1
    elseif isa(e, Integer)
      if e <= i && !first
        error("Bad index in enum: $e")
      end
      i = e
    else
      error("Bad type in enum: $e is a $(typeof(e)). Int or Symbol expected.")
    end
    first = false
  end
  Expr(:block, Any[
    Expr(:type, Any[
      Expr(:<:, Any[typ,:CEnum], Any), 
      Expr(:block, names, Any)
    ], Any),
    Expr(:call, Any[typ, values...], Any)
  ], Any)
end

end #Base

@Keno
Copy link
Contributor

Keno commented Feb 21, 2013

I'm actually not too opposed to keeping the C enums in this case since this is a rather low level library and people using it will be looking at the Cairo docs, which list the C enums. Having to translate seems like an unnecessary obstacle.

@pygy
Copy link
Author

pygy commented Feb 21, 2013

The translation is trivial (CAIRO_FORMAT_ARGB32 becomes Cairo.format.argb32), and all caps are IMO ugly.

It enables the possiblity to cache Cairo.format in a local, reducing clutter.

BTW, this is a suggestion for a general convention for representing enums in Julia. We don't have to follow the conventions of other languages when we can do better.

@timholy
Copy link
Member

timholy commented Jan 7, 2014

Enums are still under discussion in base Julia, you may want to consider bringing this up there.

@nolta
Copy link
Member

nolta commented Jan 7, 2014

I agree w/ @loladiro -- let's keep the C names.

@nolta nolta closed this as completed Jan 7, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants