Skip to content

Instantly share code, notes, and snippets.

@matfournier
Last active July 1, 2021 22:03
Show Gist options
  • Save matfournier/65247e627b1a7cdf77e74d655b698d09 to your computer and use it in GitHub Desktop.
Save matfournier/65247e627b1a7cdf77e74d655b698d09 to your computer and use it in GitHub Desktop.
Nim interface example
import
# map,
# entity,
strformat
type
Terminal* = ref TerminalObj
TerminalObj* = object of RootObj
layer*: proc (i: int)
EchoTerminal* = ref EchoTerminalObj # version that echos to console
EchoTerminalObj* = object of TerminalObj
id*: string
layerValue*: int
BearTerminal* = ref BearTerminalObj # version that uses BearLibTerminal
BearTerminalObj* = object of TerminalObj
# constructor for console version
proc newEchoTerminal*(id: string): EchoTerminal =
var t = EchoTerminal()
t.id = id
# if you didn't implement t.layer it compiles but then doStuff explodes at runtime :(
t.layer = proc(i: int) =
t.layerValue = i
return t
# actually use it
proc doStuff(terminal: Terminal) =
terminal.layer(1)
when isMainModule:
let terminal = newEchoTerminal("id")
echo fmt"terminal id is {terminal.id}"
doStuff(terminal)
echo fmt"terminal layer is still {terminal.layerValue}"
terminal.layer(4)
echo fmt"terminal layer is now {terminal.layervalue}"
@matfournier
Copy link
Author

@deech:

the simplest record of functions appears to be the easiest?

type 
  TerminalFunctions = object
    layer: proc(i: int)

proc echoTerminalFunction(): TerminalFunctions = 
  TerminalFunctions(layer: proc (i: int) = echo fmt"layer was {i}")

proc recordingTerminalFunction(layerValue: ref int): TerminalFunctions = 
  proc updateLayerValue(i: int) = 
    layerValue[] = i
  result = TerminalFunctions(layer: updateLayerValue)

when isMainModule:

  echo "trying recordinfFunctions"
  let echoTerminal = echoTerminalFunction()
  echoTerminal.layer(1)
  var layerValue: ref int
  new layerValue
  let recordLayerTerminal = recordingTerminalFunction(layerValue) # e.g. for a test
  recordLayerTerminal.layer(10)
  echo fmt"recording terminal layer is {layerValue[]}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment