"type definition not allowed inside a local scope"

question

#1

Hi.

Julia tells me that “type definition not allowed inside a local scope”.

I have a simple question - why? :slight_smile:


#2

What are you doing when you get that error?


#3

I just try to define type in a function scope :slight_smile:

function localscope()
    type Foo
         baz::Int
         qux::Float64
    end
end

localscope()

I found this comment that there are no “local types”. I wonder why.


#4

Part of the language design. Perhaps if you described your problem people would suggest solutions that work around this limitation.


#5

It’s not exactly a limitation. Firstly, it’s not clear why you would need a type definition to be local to a function. Secondly, if you need a type definition to be local to a particular scope, you can make a new module, put it there and not export it.


#6

Since people run into it sometimes, I would call it a limitation, but I agree that it is not a significant one in practice. I am curious about the use case of @Dandan though.


#7

The motivation for question was this reasoning:
Why would I need type definition in global scope if I use it only in local scope?
What if I want to declare and use type in local scope but with some name that already exists in global scope?

It was not motivated by practice and it’s not a real limitation to me. Just curiosity)
Maybe there are some arguments against this feature?


#8

There is also another question. Assuming there are only global types - why we can’t define type with some code written within a function?


#9

Why would you want a type definition that you only use in local scope? Types are mainly useful to tie together information and functions passed between multiple scopes.

You can, using eval.


#10

The scoping rules are a bit awkward, but technically we could just allow this. We now already let you make local types by using closure syntax, so this wouldn’t be anything spectacularly different. Probably not a priority for 1.0, but could perhaps be a good up-for-grabs feature.


#11

Can we get modules in local scope too while we’re at it?


#12

What’s the use case of allowing local modules? (just curious!)


#13

Currently, modules are only allowed at top level. Actually, for my purposes, broadening this to global scope would be enough. That’s so you can define modules inside macros. https://github.com/JuliaLang/julia/issues/21009


#14

It would be interesting to see a use case for macros that define modules.


#15

I’m interested so that you can chain all the code in a module. But yeah I bet there are some pretty cool applications.


#16

I suppose one use case would be for an enum like macro, that defined a baremodule with a set of constant values of different types.
I’ve done that manually a number of times, to avoid polluting a namespace, and to have easier to use names for the constants, i.e. Foo.BAR, Foo.BAZ instead of FOO_BAR, FOO_BAZ, I only need to export the module name Foo.


#17
macro macmod(block)
       return Expr(:toplevel, esc(block))
end

@macmod module Foo
       foo(x) = x^3
end

#18

Yes, this has been pointed out to me. But according to Jeff (see the linked issue), “it’s not generally correct to just replace block with toplevel, or to move code around”


#19

The main downside is that it means your macro can only be used at the toplevel. In many cases, that simply means it would be clearer to write the eval explicitly.