I'm working on an experiment using distinct strings to represent biological sequences, which come in flavors akin to languages (which I'll use in the example below). I want to make a genetic proc that, when not supplied with a type, uses the default type. For example:
type English = distinct string
type French = distinct string
type Language = distinct string
type OpenLang = Language|English|French
proc readFile[T: OpenLang = Language](filepath: string): T =
return T("") # dummy
# works
discard readFile[English]("english.txt")
discard readFile[French]("french.txt")
discard readFile[Language]("we_dont_know_what_language_at_compile_time.txt")
# how to make this work?
discard readFile("we_dont_know_what_language_at_compile_time.txt")
I could define an auxiliary function readFileAs[T] and make readFile default to Language but that seems inelegant. Is there any way in Nim to make this work?
type English = distinct string
type French = distinct string
type Language = distinct string
type OpenLang = Language|English|French
proc readFile(filepath: string; Lang: typedesc[OpenLang] = Language): Lang =
echo "Lang: ", Lang, ", path: ", filepath
return Lang("") # dummy
# works
discard readFile("english.txt", English)
discard readFile("french.txt", French)
discard readFile("we_dont_know_what_language_at_compile_time.txt", Language)
# how to make this work?
discard readFile("we_dont_know_what_language_at_compile_time.txt")
That's a great solution! Do you know of any examples in the stdlib that use this approach? I haven't seen it before in practice.
It does still seem strange though to me that there's not a way to use the regular name[T](arg) call if you want to, only name(arg, T). Is there a reason it can't be done or is it a current compiler limitation?
This problem might be better handled with a static enum, as it gives you a typeclass and also language specific dispatch.
type
Locale = enum
Unknown, English, French
Language[T: static Locale] = distinct string
proc readFile(path: string; locale: static Locale = Unknown): Language[locale] =
echo "Lang: ", locale, ", path: ", path
Language[locale]("") # dummy
proc `$`(lang: Language): string = string(lang) # Devel has a fix for borrowing typeclasses like this, but before needs this.
discard readFile("english.txt", English)
discard readFile("french.txt", French)
discard readFile("we_dont_know_what_language_at_compile_time.txt", Unknown)
discard readFile("we_dont_know_what_language_at_compile_time.txt")