Often I'll have surrounding context that I use to define something, that has 
very little relevance outside of that something. For instance:
    
    
    let placeholder = "first $delim second $delim third".split("$delim",2)
    let first = placeholder[0]
    let second = placeholder[1]
    let third = placeholder[2]
    

I will want to use first, second and third elsewhere in my program, but 
placeholder only exists to create them, and it claims the name "placeholder" so 
the next time I do something like this, I have to use "placeholder2" or 
something, and just manually avoid name conflicts.

It's tempting to say the solution is to return a tuple, but even that requires 
a dummy name 
    
    
    proc stillaplaceholder(): tuple[str,str,str] =
      const placeholder = staticRead("somefile").split("$delim",2)
      return (placeholder[0],placeholder[1],placeholder[2])
    let (first,second,third) = stillaplaceholder()
    

And often times I want to define a procedure, which isn't exactly the same as 
returning a procedure.
    
    
    var select = prepare("SELECT info FROM thingy WHERE id = ?1")
    var insert = prepare("INSERT INTO thingy DEFAULT VALUES")
    proc createThingy(id: int64): something =
      result = select.gofind(id)
      if not result:
        insert.inject()
        result = last_row_id_thing()
    

Yeah, sqlite is great, I know. But I don't want to pollute my namespace with 
"select" and "insert", and it seems silly to make a separate module for every 
table in the database that acts like this. But I can't put it in a block, 
otherwise createThingy will go out of scope! I thought about using a template...
    
    
    template createcreateThingy(name: untyped, select: string, insert: string) =
      var a = prepare(select)
      var b = prepare(insert)
      proc `name`(id: int64): something =
        ...
    

but then I end up with this ridiculous bit of code: 
    
    
    createcreateThingy(createThingy,"SELECT info FROM thingy WHERE id = 
?1","INSERT INTO thingy DEFAULT VALUES")
    

I'm really not trying to automate creation of the code _inside_ the procedure. 
I'm just trying to hide the "select" and "insert" variables. Sure I could 
prepare them every time the function is called, or make some sort of a cache to 
look up previously prepared statements, but it's nicer to just use a 
surrounding context, and have nim just know which variables are which.

Is there an elegant solution to this? Or am I just being too picky, and using 
stuff like placeholder2 is a perfectly good idea?

Reply via email to