diff --git a/.github/scripts/docs.nims b/.github/scripts/docs.nims index 24a3be7e..0940869f 100755 --- a/.github/scripts/docs.nims +++ b/.github/scripts/docs.nims @@ -19,11 +19,10 @@ let --git.url:https://github.com/noahehall/nim \ --hints:off \ --index:on \ - --multimethods:on \ + --outdir:{docsDir} \ --project \ - --threads:on \ --verbosity:0 \ - --outdir:{docsDir} \ + --warnings:off \ """ cd rootDir @@ -52,6 +51,14 @@ proc createSourceDocs: (string, int) = except OSError: ("failed to create documentation", 1) +proc createSourceDocsIndex: (string, int) = + echo "create user-serachable index HTML" + try: + fmt"buildIndex -o:{rootDir/docsDir}/theindex.html {rootDir / docsDir}".selfExec + ("user-searchable index HTML created", 0) + except OSError: + ("failed to user-searchable index", 1) + proc createTestResults: (string, int) = createTestResultsHtml() proc createDependencyGraphs: (string, int) = @@ -68,7 +75,7 @@ proc mvFilesToHtmlDocsDir: (string, int) = for output in @[ rootDir / "src/bookofnim.dot", rootDir / "src/bookofnim.png", - rootDir / "testresults.html" # TODO think this broke viewing testresults in github pages + # rootDir / "testresults.html" # TODO(noah) think this broke viewing testresults in github pages ]: output.mvFile rootDir / docsDir / output.extractFilename ("documentation moved to htmldocs dir", 0) except CatchableError: @@ -79,6 +86,7 @@ when isMainModule: installDeps, deletePrevdocs, createSourceDocs, + createSourceDocsIndex, createDependencyGraphs, createTestResults, mvFilesToHtmlDocsDir # must occur last diff --git a/README.md b/README.md index 61ed7d4d..5535bceb 100644 --- a/README.md +++ b/README.md @@ -16,21 +16,28 @@ - fullstack is a first principle for us; nim redefines what that means - many application developers are moving to/incorporating rust/go in their stack; suspend judgment and consider nim for (many, but definitely) these reasons +- first-class features - [cross compile applications](https://nim-lang.org/docs/nimc.html#crossminuscompilation) - [cross platform scripts](https://nim-lang.org/docs/nims.html#benefits) - [robust application & script configuration](https://nim-lang.org/docs/parsecfg.html) - - [documentation is a first class citizen](https://nim-lang.org/docs/docgen.html) + - [documentation + html generation](https://nim-lang.org/docs/docgen.html) - [with first class support for reStructured text](https://docutils.sourceforge.io/docs/user/rst/quickref.html) - - [testing is a first class citizen](https://nim-lang.github.io/Nim/testament.html) + - [Holistic Test Suite](https://nim-lang.github.io/Nim/testament.html) + - TODO add unittest here even tho we dont use it - [with html reports](https://noahehall.github.io/nim/htmldocs/testresults.html) - [and valgrind integration for memory leaks](https://valgrind.org/) - - [first class support for postgres, mysql](https://nim-lang.org/docs/lib.html#impure-libraries-database-support) - - [including a generic ODBC wrapper for other dbs](https://nim-lang.org/docs/db_odbc.html) - [future proof design philisophy](https://www.youtube.com/watch?v=aDi50K_Id_k) - [with ergonomic APIs](https://nim-lang.org/docs/apis.html) - [various pragmas to customize, restrict and enhance the compiler and runtime](https://nim-lang.github.io/Nim/manual.html#pragmas) - - [community forum](https://forum.nim-lang.org/) - [spiderman's uncle](https://nim-lang.org/docs/tut3.html) +- core-developer supported features + - [core-developer support for postgres, mysql](https://nim-lang.org/docs/lib.html#impure-libraries-database-support) + - [including a generic ODBC wrapper for other dbs](https://nim-lang.org/docs/db_odbc.html) + - TODO: i think the docs are still under nimlang, but the packages have moved to nimble + - add channels to this list +- community driven + - [community-driven forum](https://forum.nim-lang.org/) + - TODO add the links to the other places ## recommended ramp up @@ -128,6 +135,9 @@ internal nimlang +- [AAA: nims index ctrl f-it](https://nim-lang.github.io/Nim/theindex.html) +- [stable (i.e. 1.6\*)](https://nim-lang.org/docs/manual.html) +- [v2 (i.e. >= 1.9.3)](https://nim-lang.github.io/Nim/manual.html) - [std library](https://nim-lang.org/docs/lib.html) - [nim manual](https://nim-lang.org/docs/manual.html) - [api design](https://nim-lang.org/docs/apis.html) diff --git a/bookofnim.nimble b/bookofnim.nimble index 30b9bd1d..d98a4f32 100644 --- a/bookofnim.nimble +++ b/bookofnim.nimble @@ -1,9 +1,11 @@ from strutils import unindent import os +const nimv = "1.9.3" ## sync on nim version + # Package -version = "1.9.3" # syncd to nim version +version = nimv author = "noahehall" description = """ book of nim: bow to the crown @@ -15,7 +17,7 @@ srcDir = "src" # Dependencies -requires "nim >= 1.6.12" +requires "nim >= " & nimv # Tasks @@ -27,9 +29,10 @@ task copyGitHooks, "copies .github/hooks to .git/hooks": let fromDir = currentSourcePath() / ".." / ".github/hooks" for kind, path in fromDir.walkDir: if kind == pcFile and path[(path.len - 3) .. ^1] == ".sh": - echo "installing git hook: ", path.lastPathPart # git hooks dont have file extensions - path.cpFile toDir / path.lastPathPart[0 .. ^4] + let githook = path.lastPathPart[0 .. ^4] + echo "installing git hook: ", githook + path.cpFile toDir / githook task postclone, "executes post-repo-clone tasks": diff --git a/config.nims b/config.nims index 17277c2f..9a77c197 100644 --- a/config.nims +++ b/config.nims @@ -1,40 +1,108 @@ -# --colors:on # breaks vscode run code extension -# --experimental:codeReordering dont use or fear the amount of logs it produces -# FYI: hint/warningAsError requires switch() syntax +discard """ +- This config aims to provide sensible defaults for web applications +- push & pop specific pragmas in source when required, e.g. hint[Name]:off ---assertions:off +the available environments include: +- ENV=DEV: relaxes strict mode to allow for active development of features +- ENV=PERF: danger mode +- ENV=SIZE: reduced application size +- ENV=SPEED: increased application speed +- else uses --define:release + +the following envvars, if set to any value, will enable additional settings +- CI: no parallel + force builds with verbosity set to 2 +- TEST: stacktraces turned on with verbosity set to 2 + - see tests/config.nims for more (we borrowed heavily from nim's test config.nims) + +the following compiler switches are set for all environments focusing on +developing applications with nim in a ghetto `strict` mode; in particular +- all deprecations are errors +- hints promoting good coding hygine are turned into errors +- warnings that could materialize into bugs are turned into errors +- nimPreviewSlimSystem is set to remove deprecated symbols and other things + +The aforementioned settings will disrupt your development velocity as you transition. +depending on the size of your code base and deviation from `strict` standards +will likely require major refactoring + +FYI: +- --colors:on > breaks vscode run code extension +- --experimental:codeReordering > will be replaced with a better solution in the future +- --experimental:notnil > prefer strictNotNil unless your consuming unreliable packages + - however strictNotNil currently throws on nim source, so we use notnil +- [hint|warning][AsError] > requires switch() syntax in configs +- the following are removed until https://github.com/noahehall/nim/issues/40 + --experimental:views + --experimental:strictCaseObjects + switch("warningAsError", "BareExcept:on") + switch("warningAsError", "ProveInit:on") + switch("warningAsError", "ResultUsed:on") + switch("warningAsError", "Uninit:on") +- the following require more time to understand impact and usecase + - --define:useRealtimeGC # @see https://nim-lang.github.io/Nim/refc.html +""" + +--assertions:off # should only be enabled in dev, use doAssert for hard checks --checks:on --debugger:native --deepcopy:on # required for mm:orc/arc +--define:futureLogging +--define:nimPreviewCstringConversion +--define:nimPreviewSlimSystem --define:nimStrictDelete --define:release --define:ssl --define:threadsafe --errorMax:1 ---experimental:strictEffects ---forceBuild:on +--experimental:callOperator +--experimental:dotOperators +--experimental:flexibleOptionalParams +--experimental:notnil +--experimental:parallel +--experimental:strictDefs +--experimental:strictFuncs --hints:on ---mm:orc +--mm:orc # required for async apps, else use arc --multimethods:on --panics:on --parallelBuild:0 +--spellSuggest --stackTraceMsgs:off ---styleCheck:error # can push specific pragmas, e.g. hint[Name]:off ---threads:on +--styleCheck:error --tlsEmulation:on --unitsep:on # ASCII unit separator between error msgs --verbosity:0 --warnings:on -switch("hint","GlobalVar:off") # spams u to death +switch("hint", "CC:off") +switch("hint", "CodeBegin:off") +switch("hint", "CodeEnd:off") +switch("hint", "CondTrue:off") +switch("hint", "GCStats:off") +switch("hint", "GlobalVar:off") # spams u to death +switch("hint", "Link:off") +switch("hint", "Path:off") +switch("hint", "Processing:off") +switch("hint", "Success:off") +switch("hintAsError", "ConvFromXtoItselfNotNeeded:on") +switch("hintAsError", "ConvToBaseNotNeeded:on") switch("hintAsError", "DuplicateModuleImport:on") +switch("hintAsError", "LineTooLong:on") switch("hintAsError", "Performance:on") switch("hintAsError", "XDeclaredButNotUsed:on") +switch("warningAsError", "CannotOpenFile:on") +switch("warningAsError", "CastSizes:on") switch("warningAsError", "ConfigDeprecated:on") +switch("warningAsError", "CStringConv:on") switch("warningAsError", "Deprecated:on") +switch("warningAsError", "EachIdentIsTuple:on") +switch("warningAsError", "EnumConv:on") switch("warningAsError", "GcUnsafe:on") switch("warningAsError", "HoleEnumConv:on") -switch("warningAsError", "ResultUsed:on") +switch("warningAsError", "OctalEscape:on") +switch("warningAsError", "SmallLshouldNotBeUsed:on") +switch("warningAsError", "UnreachableElse:on") switch("warningAsError", "UnusedImport:on") + case getCommand(): of "c", "cc", "cpp", "objc": --lineDir:on @@ -62,34 +130,29 @@ case getEnv "ENV": --danger of "SIZE": # @see https://github.com/ee7/binary-size - --checks:off + --define:useMalloc --opt:size --passC:"-flto" --passL:"-flto" of "SPEED": - --checks:off --opt:speed --passC:"-flto" --passL:"-s" else: discard +case getEnv "ENV": + of "SIZE", "SPEED", "PERF": + --checks:off + --hints:off + --lineDir:off + --lineTrace:off + --stackTrace:off + --warnings:off + else: discard + case existsEnv "CI": of true: + --forceBuild:on --parallelBuild:1 --verbosity:2 else: discard - -when (NimMajor, NimMinor, NimPatch) <= (1,6,12): - # throws in v2, maybe its no longer experimental? - --experimental:implicitDeref - # throws on nim source code - # @see https://github.com/nim-lang/Nim/issues/21713 - switch("hintAsError", "DuplicateModuleImport:off") - switch("hintAsError", "Performance:off") - switch("hintAsError", "XDeclaredButNotUsed:off") - switch("warningAsError", "Deprecated:off") - switch("warningAsError", "HoleEnumConv:off") # only in ci on nim source - switch("warningAsError", "UnusedImport:off") # only in ci on nim source -else: - --define:futureLogging - switch("warningAsError", "CastSizes:on") diff --git a/htmldocs/bookofnim/deepdives/assertions.html b/htmldocs/bookofnim/deepdives/assertions.html new file mode 100644 index 00000000..5ce85c13 --- /dev/null +++ b/htmldocs/bookofnim/deepdives/assertions.html @@ -0,0 +1,240 @@ + + + + + + + +src/bookofnim/deepdives/assertions + + + + + + + + + + + + +
+
+

src/bookofnim/deepdives/assertions

+
+
+
+ + +
+ +
+ Search: +
+
+ Group by: + +
+ + +
+
+ Source   +Edit   + +
+ +

+

assertions

+

TLDR

+

links

+ +

assertion procs

+

assert

  • -d:danger or --asertions:off to remove from compilation
    +
  • +
  • --assertions:on to keep them in compiled output
    +
  • +
  • useful for soft guard, pre & post conditions if using design by contract
  • +
  • i think drnim even extends this further
  • +
+ +

doAssert

  • always on regardless of flags
  • +
  • can be used to check for specific errors with doAssertRaises(woop): block
  • +
  • useful for hard checks & design by contract
  • +
+

+
+

Vars

+
+
+
wrong`gensym9 = false
+
+ + + Source   +Edit   + +
+
+ +
+
+
+

Consts

+
+
+
begin`gensym9 = "expected raising \'KeyError\', instead"
+
+ + + Source   +Edit   + +
+
+
+
loc`gensym1 = (filename: "assertions.nim", line: 36, column: 0)
+
+ + + Source   +Edit   + +
+
+
+
loc`gensym8 = (filename: "assertions.nim", line: 50, column: 0)
+
+ + + Source   +Edit   + +
+
+
+
msgEnd`gensym9 = " by: \nraise newException(KeyError, \"key error\")"
+
+ + + Source   +Edit   + +
+
+
+
ploc`gensym1 = "assertions.nim(36, 1)"
+
+ + + Source   +Edit   + +
+
+
+
ploc`gensym8 = "assertions.nim(50, 1)"
+
+ + + Source   +Edit   + +
+
+ +
+
+
+

Templates

+
+
+
+
template raisedForeign`gensym9() {.gensym.}
+
+ + + Source   +Edit   + +
+
+ +
+ +
+
+ +
+
+ + +
+
+ + + + + + diff --git a/htmldocs/bookofnim/deepdives/assertions.idx b/htmldocs/bookofnim/deepdives/assertions.idx new file mode 100644 index 00000000..db016036 --- /dev/null +++ b/htmldocs/bookofnim/deepdives/assertions.idx @@ -0,0 +1,15 @@ +nimTitle assertions bookofnim/deepdives/assertions.html module src/bookofnim/deepdives/assertions 0 +nim loc`gensym1 bookofnim/deepdives/assertions.html#loc`gensym1 const loc`gensym1 46 +nim ploc`gensym1 bookofnim/deepdives/assertions.html#ploc`gensym1 const ploc`gensym1 47 +nim loc`gensym8 bookofnim/deepdives/assertions.html#loc`gensym8 const loc`gensym8 46 +nim ploc`gensym8 bookofnim/deepdives/assertions.html#ploc`gensym8 const ploc`gensym8 47 +nim wrong`gensym9 bookofnim/deepdives/assertions.html#wrong`gensym9 var wrong`gensym9 97 +nim begin`gensym9 bookofnim/deepdives/assertions.html#begin`gensym9 const begin`gensym9 98 +nim msgEnd`gensym9 bookofnim/deepdives/assertions.html#msgEnd`gensym9 const msgEnd`gensym9 99 +nim raisedForeign`gensym9 bookofnim/deepdives/assertions.html#raisedForeign`gensym9.t template raisedForeign`gensym9() 100 +heading assertions bookofnim/deepdives/assertions.html#assertions assertions 0 +heading TLDR bookofnim/deepdives/assertions.html#assertions-tldr TLDR 0 +heading links bookofnim/deepdives/assertions.html#assertions-links links 0 +heading assertion procs bookofnim/deepdives/assertions.html#assertions-assertion-procs assertion procs 0 +heading assert bookofnim/deepdives/assertions.html#assertions-assert assert 0 +heading doAssert bookofnim/deepdives/assertions.html#assertions-doassert doAssert 0 diff --git a/htmldocs/bookofnim/helloworld/modules/typeSystem.html b/htmldocs/bookofnim/helloworld/modules/typeSystem.html new file mode 100644 index 00000000..a07aa91b --- /dev/null +++ b/htmldocs/bookofnim/helloworld/modules/typeSystem.html @@ -0,0 +1,670 @@ + + + + + + + +src/bookofnim/helloworld/modules/typeSystem + + + + + + + + + + + + +
+
+

src/bookofnim/helloworld/modules/typeSystem

+
+
+
+ + +
+ +
+ Search: +
+
+ Group by: + +
+ + +
+
+ Source   +Edit   + +
+ +

+

nims type system

+

TLDR

  • the potential for effectively using typedesc deserves multiple readings of the docs
  • +
  • not understanding bind once vs bind many can produce interesting bugs in your code
  • +
+ +

links

+ +

TODOs

  • read through the scala notes and try to replicate the algebraic DTs
  • +
  • move all the type logic stuff in here
  • +
  • metatype examples
  • +
  • type bound operator examples (and should probably reread those docs)
  • +
  • probably should reread the typedesc docs
  • +
  • symbol lookups in generics
    • mixin statement
    • +
    • bind statement
    • +
    • delegating bind statements
    • +
    +
  • +
  • generics and the method call syntax
    • theres a [:X] syntax that doesnt conflict with the method call syntax (blah.method) +
    • +
    +
  • +
  • example with is operator for generics
  • +
+ +

metatypes

  • untyped lookup symbols & perform type resolution after the expression is interpreted & checked
    • i.e. expression is lazily resolved to its value (for templates)
    • +
    • use to pass a block of statements
    • +
    +
  • +
  • typed: semantic checker evaluates and transforms args before expression is interprted & checked
    • an expression that is eagerly resolved to its value (for templates)
    • +
    • i.e. whenever u set a type in a signature its resolved immediately
    • +
    +
  • +
  • typedesc a type description
  • +
  • void absence of any type, generally used as proc return type
  • +
+ +

type bound operators

  • a proc or func starting with = but isnt an operator (yet still uses backticks in signature)
    • is always visible to the type, i.e. regardless of visibility of the definition
    • +
    • i.e. are bound to the Type and lifted to global scope
    • +
    +
  • +
  • unrelated to propertie setters which end in = despite syntax similarities
    • =copy
    • +
    • =destroy Generic destructor implementation
    • +
    • =sink Generic sink implementation
    • +
    • =trace Generic trace implementation
    • +
    • =deepcopy
    • +
    • =wasMoved
    • +
    +
  • +
+ +

type classes

  • pseudo type that can be used to match via the is operator
  • +
  • are compile-time constraints enforced at instantiation, not dynamically at runtime
  • +
  • in addition, every generic type creates a type class of the same name
    • native: object, tuple, enuim, proc, iterator, ref, ptr, var, distinct, array, set, seq, auto
    • +
    +
  • +
  • can be conbined, e.g. type RecordType = (object or tuple) or as object | tuple
  • +
  • will be intantiated (overloaded) once for each unique combination used within the program
    • bind once types: each are bound once per concrete type
    • +
    • bind many types: each are bound for every concrete type if distinct|typedesc is applied
    • +
    +
  • +
+ +

typedesc

  • nim treats the names of types as regular values in certain contexts in the compilation phase
  • +
  • typedesc is a generic type for all types denoting the type class of all types
    • i.e. all types are really typedescblah, e.g. int == typedescint
    • +
    +
  • +
  • procs using typedesc params are implicitly generic
    • i.e. p(a: typedesc) == p[T](a: typedesc[T])
    • +
    • i.e. p(a: typedesc; b:a) == p[T](a: typedesc[T]; b: T) == p(int, 4)
    • +
    +
  • +
+ +

staticT

  • must be constant expressions
  • +
  • are treated as generic parameters, thus compiled for each unique type T
  • +
  • proc parameters can also be static,
  • +
  • expressions (e.g. proc invocations) can be coereced to static(blah()) for compile time evalution
  • +
+ +

converters

  • routine that (re)defines conversion between two types
  • +
  • can be explicitly invoked for readability
  • +
  • converter chaining is not automatic
    • i.e. a > b > c exist, but a > c does not occur automatically
    • +
    +
  • +
+ +

inspection

  • type(x): retrieve the type of x, discouraged should use typeof
  • +
  • typeof(x, mode = typeofIter): retrieve the type of x
  • +
  • typeOfProc: retrieve the result of a proc, i.e. typeof x, typeOfProc
  • +
  • TypeofMode: enumtypeofProc|typeofIter second param to typeof
  • +
+ +

generics

  • abc
  • +
+

+
+

Types

+
+
+
BiggerMoney = distinct BigMoney
+
+ + + Source   +Edit   + +
+
+
+
BiggestMoney {.borrow: `.`.} = distinct BigMoney
+
+ + + Source   +Edit   + +
+
+
+
BigMoney = int
+
+ + + Source   +Edit   + +
+
+
+
MyType = ref object of RootObj
+
+ + + Source   +Edit   + +
+
+
+
Option[T] = object
+  
+
+ + + Source   +Edit   + +
+
+
+
OtherRecord = tuple[wtf: string]
+
+ + + Source   +Edit   + +
+
+
+
RecordType = (typeof myRecord) or object | tuple
+
+ + + Source   +Edit   + +
+
+
+
StrOrInt = string | int
+
+ + + Source   +Edit   + +
+
+ +
+
+
+

Vars

+
+
+
ii: int
+
+ + + Source   +Edit   + +
+
+
+
instance: MyType = MyType()
+
+ + + Source   +Edit   + +
+
+
+
myInt = 10
+
+ + + Source   +Edit   + +
+
+
+
myRecord: tuple[wtf: string] = (wtf: "yo")
+
+ + + Source   +Edit   + +
+
+
+
othervar: string = ""
+
+ + + Source   +Edit   + +
+
+
+
somevar: seq[char] = @['n', 'o', 'a', 'h']
+
+ + + Source   +Edit   + +
+
+
+
utherRecord: OtherRecord = (wtf: "yo2")
+
+ + + Source   +Edit   + +
+
+
+
x`gensym0: int = 42
+
+ + + Source   +Edit   + +
+
+ +
+
+
+

Lets

+
+
+
aa = Option[int](hasValue: true, value: 1)
+
+ + + Source   +Edit   + +
+
+
+
bb = Option[int](hasValue: true, value: 2)
+
+ + + Source   +Edit   + +
+
+
+
myStaticVar = 3
+
+ + +static(x): force the compile-time evaluation of the given expression + Source   +Edit   + +
+
+
+
thisInt: StrOrInt = 1
+
+ + + Source   +Edit   + +
+
+
+
thizString: StrOrInt = "1"
+
+ + + Source   +Edit   + +
+
+
+
x: string = "ima string"
+
+ + + Source   +Edit   + +
+
+
+
y: typeof(x) = "ima also a string"
+
+ + + Source   +Edit   + +
+
+ +
+
+
+

Procs

+
+
+
+
proc doubleFloat(x: float): float {....raises: [], tags: [], forbids: [].}
+
+ + + Source   +Edit   + +
+
+ +
+
+
+
proc fieldsPrint[T: distinct tuple | object](first, second: T)
+
+ + + Source   +Edit   + +
+
+ +
+
+
+
proc foo[T](i: T)
+
+ + + Source   +Edit   + +
+
+ +
+
+
+
proc printFields[T: RecordType](rec: T)
+
+ + + Source   +Edit   + +
+
+ +
+
+
+
proc wtf[T](a: T): auto
+
+ + + Source   +Edit   + +
+
+ +
+ +
+
+
+

Converters

+
+
+
+
converter get[T](x: Option[T]): T
+
+ + create an implicit conversion for OptionT now Optionint + Optionint works + Source   +Edit   + +
+
+ +
+
+
+
converter toBool(x: int): bool {....raises: [], tags: [], forbids: [].}
+
+ + + Source   +Edit   + +
+
+ +
+ +
+
+
+

Templates

+
+
+
+
template declareVariableWithType(T: typedesc; value: T:type)
+
+ + + Source   +Edit   + +
+
+ +
+ +
+
+ +
+
+ + +
+
+ + + + + + diff --git a/htmldocs/bookofnim/helloworld/modules/typeSystem.idx b/htmldocs/bookofnim/helloworld/modules/typeSystem.idx new file mode 100644 index 00000000..c673a26f --- /dev/null +++ b/htmldocs/bookofnim/helloworld/modules/typeSystem.idx @@ -0,0 +1,44 @@ +nimTitle typeSystem bookofnim/helloworld/modules/typeSystem.html module src/bookofnim/helloworld/modules/typeSystem 0 +nim BigMoney bookofnim/helloworld/modules/typeSystem.html#BigMoney type BigMoney 111 +nim StrOrInt bookofnim/helloworld/modules/typeSystem.html#StrOrInt type StrOrInt 114 +nim thizString bookofnim/helloworld/modules/typeSystem.html#thizString let thizString 115 +nim thisInt bookofnim/helloworld/modules/typeSystem.html#thisInt let thisInt 116 +nim BiggerMoney bookofnim/helloworld/modules/typeSystem.html#BiggerMoney type BiggerMoney 122 +nim BiggestMoney bookofnim/helloworld/modules/typeSystem.html#BiggestMoney type BiggestMoney 123 +nim wtf bookofnim/helloworld/modules/typeSystem.html#wtf,T proc wtf[T](a: T): auto 143 +nim foo bookofnim/helloworld/modules/typeSystem.html#foo,T proc foo[T](i: T) 154 +nim ii bookofnim/helloworld/modules/typeSystem.html#ii var ii 156 +nim myRecord bookofnim/helloworld/modules/typeSystem.html#myRecord var myRecord 164 +nim OtherRecord bookofnim/helloworld/modules/typeSystem.html#OtherRecord tuple OtherRecord 167 +nim RecordType bookofnim/helloworld/modules/typeSystem.html#RecordType type RecordType 172 +nim printFields bookofnim/helloworld/modules/typeSystem.html#printFields,T proc printFields[T: RecordType](rec: T) 175 +nim utherRecord bookofnim/helloworld/modules/typeSystem.html#utherRecord var utherRecord 179 +nim fieldsPrint bookofnim/helloworld/modules/typeSystem.html#fieldsPrint,T,T proc fieldsPrint[T: distinct tuple | object](first, second: T) 187 +nim declareVariableWithType bookofnim/helloworld/modules/typeSystem.html#declareVariableWithType.t,typedesc,typedesc template declareVariableWithType(T: typedesc; value: T:type) 193 +nim x`gensym0 bookofnim/helloworld/modules/typeSystem.html#x`gensym0 var x`gensym0 194 +nim Option bookofnim/helloworld/modules/typeSystem.html#Option object Option 200 +nim aa bookofnim/helloworld/modules/typeSystem.html#aa let aa 206 +nim bb bookofnim/helloworld/modules/typeSystem.html#bb let bb 207 +nim get bookofnim/helloworld/modules/typeSystem.html#get.c,Option[T] converter get[T](x: Option[T]): T 209 +nim toBool bookofnim/helloworld/modules/typeSystem.html#toBool.c,int converter toBool(x: int): bool 217 +nim somevar bookofnim/helloworld/modules/typeSystem.html#somevar var somevar 222 +nim othervar bookofnim/helloworld/modules/typeSystem.html#othervar var othervar 223 +nim MyType bookofnim/helloworld/modules/typeSystem.html#MyType type MyType 229 +nim instance bookofnim/helloworld/modules/typeSystem.html#instance var instance 230 +nim myStaticVar bookofnim/helloworld/modules/typeSystem.html#myStaticVar let myStaticVar 241 +nim myInt bookofnim/helloworld/modules/typeSystem.html#myInt var myInt 246 +nim doubleFloat bookofnim/helloworld/modules/typeSystem.html#doubleFloat,float proc doubleFloat(x: float): float 248 +nim x bookofnim/helloworld/modules/typeSystem.html#x let x 254 +nim y bookofnim/helloworld/modules/typeSystem.html#y let y 255 +heading nims type system bookofnim/helloworld/modules/typeSystem.html#nims-type-system nims type system 0 +heading TLDR bookofnim/helloworld/modules/typeSystem.html#nims-type-system-tldr TLDR 0 +heading links bookofnim/helloworld/modules/typeSystem.html#nims-type-system-links links 0 +heading TODOs bookofnim/helloworld/modules/typeSystem.html#nims-type-system-todos TODOs 0 +heading metatypes bookofnim/helloworld/modules/typeSystem.html#nims-type-system-metatypes metatypes 0 +heading type bound operators bookofnim/helloworld/modules/typeSystem.html#nims-type-system-type-bound-operators type bound operators 0 +heading type classes bookofnim/helloworld/modules/typeSystem.html#nims-type-system-type-classes type classes 0 +heading typedesc bookofnim/helloworld/modules/typeSystem.html#nims-type-system-typedesc typedesc 0 +heading staticTT bookofnim/helloworld/modules/typeSystem.html#nims-type-system-statictt staticT 0 +heading converters bookofnim/helloworld/modules/typeSystem.html#nims-type-system-converters converters 0 +heading inspection bookofnim/helloworld/modules/typeSystem.html#nims-type-system-inspection inspection 0 +heading generics bookofnim/helloworld/modules/typeSystem.html#nims-type-system-generics generics 0 diff --git a/src/bookofnim.nim b/src/bookofnim.nim index cdfec5a9..267a7ac3 100644 --- a/src/bookofnim.nim +++ b/src/bookofnim.nim @@ -18,7 +18,7 @@ links ----- -- [latest test results](https://noahehall.github.io/nim/htmldocs/testresults.html) +- [latest test results](https://noahehall.github.io/nim/testresults.html) - use nims devel branch until the online documentation for v2 is ready - [docs](https://github.com/nim-lang/Nim/tree/devel/doc) - [system](https://github.com/nim-lang/Nim/blob/devel/lib/system.nim) @@ -31,10 +31,10 @@ links {.push warning[UnusedImport]:off .} -# latest Nim v1 import bookofnim / helloworld / helloworld ## basic nim import bookofnim / deepdives / [ + assertions, ## all types of assertions asyncPar, ## concurrency, parallelism (except async servers) collections, ## non list/queues, e.g. arrays and seqs containers, ## tuples, tables and object diff --git a/src/bookofnim/backends/nodeBrowser.nim b/src/bookofnim/backends/nodeBrowser.nim index 7ca6099d..2505ae3a 100644 --- a/src/bookofnim/backends/nodeBrowser.nim +++ b/src/bookofnim/backends/nodeBrowser.nim @@ -22,12 +22,12 @@ TODOs links ----- -- https://nim-lang.org/docs/dom.html (js) -- https://nim-lang.org/docs/asyncjs.html (js) -- https://nim-lang.org/docs/jsbigints.html (js) -- https://nim-lang.org/docs/jsconsole.html (js) -- https://nim-lang.org/docs/jscore.html (js) -- https://nim-lang.org/docs/jsffi.html (js) +- https://nim-lang.github.io/Nim/dom.html (js) +- https://nim-lang.github.io/Nim/asyncjs.html (js) +- https://nim-lang.github.io/Nim/jsbigints.html (js) +- https://nim-lang.github.io/Nim/jsconsole.html (js) +- https://nim-lang.github.io/Nim/jscore.html (js) +- https://nim-lang.github.io/Nim/jsffi.html (js) - [fusion js sets](https://nim-lang.github.io/fusion/src/fusion/js/jssets.html) - [fusion js xmlhttprequest](https://nim-lang.github.io/fusion/src/fusion/js/jsxmlhttprequest.html) - [fusion js xmlserializer](https://nim-lang.github.io/fusion/src/fusion/js/jsxmlserializer.html) diff --git a/src/bookofnim/backends/targets/android.nim b/src/bookofnim/backends/targets/android.nim index a5b5b0a5..bf315aa3 100644 --- a/src/bookofnim/backends/targets/android.nim +++ b/src/bookofnim/backends/targets/android.nim @@ -1,4 +1,5 @@ -#[ +##[ - [making android app forum post](https://forum.nim-lang.org/t/8491) -]# +- [godot](https://github.com/pragmagic/godot-nim#made-with-godot-nim) +]## diff --git a/src/bookofnim/backends/targets/gameboyAdvance.nim b/src/bookofnim/backends/targets/gameboyAdvance.nim index de439158..cc332166 100644 --- a/src/bookofnim/backends/targets/gameboyAdvance.nim +++ b/src/bookofnim/backends/targets/gameboyAdvance.nim @@ -1,4 +1,4 @@ -#[ - todo - https://github.com/exelotl/natu -]# +##[ +- [natu](https://github.com/exelotl/natu) +- https://forum.nim-lang.org/t/8375 +]## diff --git a/src/bookofnim/backends/targets/ios.nim b/src/bookofnim/backends/targets/ios.nim index a1980036..1aa59776 100644 --- a/src/bookofnim/backends/targets/ios.nim +++ b/src/bookofnim/backends/targets/ios.nim @@ -1,3 +1,4 @@ -#[ - todo -]# +##[ + +- [godot](https://github.com/pragmagic/godot-nim#made-with-godot-nim) +]## diff --git a/src/bookofnim/backends/targets/iot.nim b/src/bookofnim/backends/targets/iot.nim new file mode 100644 index 00000000..ef2ad96f --- /dev/null +++ b/src/bookofnim/backends/targets/iot.nim @@ -0,0 +1,3 @@ +##[ +- [nesper](https://github.com/elcritch/nesper) +]## diff --git a/src/bookofnim/backends/targets/shell.nims b/src/bookofnim/backends/targets/shell.nims index 0c53983b..b4d38e70 100644 --- a/src/bookofnim/backends/targets/shell.nims +++ b/src/bookofnim/backends/targets/shell.nims @@ -21,7 +21,7 @@ links - [nimscript part 3](https://peterme.net/creating-condensed-shared-libraries-embedding-nimscript-pt-3.html) - high impact - [nimscript compatibility tests](https://github.com/nim-lang/Nim/blob/devel/tests/test_nimscript.nims) - - [nimscript spec (including tasks)](https://nim-lang.org/docs/nimscript.html) + - [nimscript spec (including tasks)](https://nim-lang.github.io/Nim/nimscript.html) TODOs ----- diff --git a/src/bookofnim/deepdives/README.md b/src/bookofnim/deepdives/README.md index 70f683a0..f90a2513 100644 --- a/src/bookofnim/deepdives/README.md +++ b/src/bookofnim/deepdives/README.md @@ -4,7 +4,7 @@ ## todo -- [everything in the std library](https://nim-lang.org/docs/lib.html) +- [everything in the std library](https://nim-lang.github.io/Nim/lib.html) - nimgrep - niminst - nimpretty diff --git a/src/bookofnim/deepdives/assertions.nim b/src/bookofnim/deepdives/assertions.nim new file mode 100644 index 00000000..f57fa59c --- /dev/null +++ b/src/bookofnim/deepdives/assertions.nim @@ -0,0 +1,60 @@ +## +## assertions +## ========== + +##[ +## TLDR +- assert vs doAssert + - assert: designed for tests + - -d:danger or --asertions:off to remove from compilation + - --assertions:on to keep them in compiled output + - doAssert: designed for design by contract (IMO) + - are never removed from compiled output + - i think drnim even extends this further + +links +----- +- high impact + - [assertions](https://nim-lang.github.io/Nim/assertions.html) + + +## assertion + +assertion procs +--------------- +- assert(cond, msg) throws if cond evaluates to false; designed for unit tests +- doAssert(cond, msg) see assert, always on +- doAssertRaises(ThisException): code that raises ThisException +- failedAssertImpl(msg) called when an assertion fails +- raiseAssert(msg) raises an AssertionDefect + +]## + +echo "############################ assertions" + +import std/assertions + +# can be turned off +assert "a" == $'a' + +try: + # handles assertions in the current block + onFailedAssert msg: + # assert handler logic + let m = "assert handled: " & msg + raise newException(CatchableError, m) + # all assertions will be managed + doAssert 1 == 2, "1 !== 2" +except CatchableError as e: + echo e.msg + +# is always turned on regardless of --assertions flag +doAssert 1 < 2, "failure msg" + +doAssertRaises KeyError: + raise newException(KeyError, "key error") + +when false: + doAssertRaises ValueError: + echo "I dont raise a value error" + echo "try, except wont catch me" diff --git a/src/bookofnim/deepdives/asyncPar.nim b/src/bookofnim/deepdives/asyncPar.nim index 26548db8..5a5458be 100644 --- a/src/bookofnim/deepdives/asyncPar.nim +++ b/src/bookofnim/deepdives/asyncPar.nim @@ -1,63 +1,60 @@ ## -## concurrency and parallelism -## =========================== -## [bookmark](https://nim-lang.org/docs/asyncstreams.html) +## concurrency and parallelism (V2) +## ================================ +## [bookmark](https://nim-lang.github.io/Nim/asyncstreams.html) ##[ ## TLDR -- see runtimeMemory.nim for more on threads, thread synchronization, memory and GC -- see servers.nim for async server stuff +- changes in v2 + - system.thread moved to std/typedthreads + - system.threads still works in v2, but you should prefer std/typedthreads + - [dont use threadpool.{parallel/spawn} until clarification provided](https://forum.nim-lang.org/t/10205) + - perhaps stay away from threadpool alltogether +- see + - memoryRuntime.nim for more on threads, thread synchronization, memory and GC + - servers.nim for async server stuff + - opensource/channels.nim for the channels nimble package - you need the following for any thread related logic - required: --threads:on switch - should use: std/locks - you need the following for any async stuff - getFuturesInProgress requires --define:futureLogging -- its useful to think about threads and channels using the actor model - - actor: a procedure recreated on a thread to execute some logic - - its simpler for actors to pull/push data via a channel to/from other actors - - else you can pass data between actors through a thread when its created - - an actor can create additional actors/threads/channels - - channel: the bus in which data is sent between actors - - channels defined on the main/current thread are available to all sibling actors - - channels not defined on the main thread must be passed to other threads by ptr via an actor - - thread: where execution occurs on a CPU, 12-core machine has 12 concurrent execution contexts - - only a single thread can execute at any given time per cpu, timesharing occurs otherwise - - Thread[void]: no data is passed via thread to its actor; the actor uses a channel only - - Thread[NotVoid]: on thread creation, instance of NotVoid is expected and passed to its actor - - in order to pass multiple params, use something like a tuple/array/etc - links ----- - other - - peter - - [multitasking](https://peterme.net/multitasking-in-nim.html) - - [async programming](https://peterme.net/asynchronous-programming-in-nim.html) - [status-im chronos: alternative asyncdispatch](https://github.com/status-im/nim-chronos) + - [multitasking](https://peterme.net/multitasking-in-nim.html) + - [async programming](https://peterme.net/asynchronous-programming-in-nim.html) + - [guards and locks doc](https://nim-lang.github.io/Nim/manual.html#guards-and-locks) + - [parallel & spawn intro](https://nim-lang.github.io/Nim/manual_experimental.html#parallel-amp-spawn) - system - - [parallel & spawn intro](https://nim-lang.org/docs/manual_experimental.html#parallel-amp-spawn) - - [system channels](https://nim-lang.org/docs/channels_builtin.html) - - [system par loop iterator](https://nim-lang.org/docs/system.html#%7C%7C.i%2CS%2CT%2Cstaticstring) - - [system threads](https://nim-lang.org/docs/threads.html) - - [threads intro](https://nim-lang.org/docs/manual.html#threads) -- pkgs - - [async dispatch (event loop)](https://nim-lang.org/docs/asyncdispatch.html) - - [async file](https://nim-lang.org/docs/asyncfile.html) - - [async futures](https://nim-lang.org/docs/asyncfutures.html) - - [async streams](https://nim-lang.org/docs/asyncstreams.html) - - [lock and condition vars](https://nim-lang.org/docs/locks.html) - - [parallel tasks](https://nim-lang.org/docs/tasks.html) - - [thread pool](https://nim-lang.org/docs/threadpool.html) + - [|| is the system par loop iterator](https://nim-lang.github.io/Nim/system.html#%7C%7C.i%2CS%2CT%2Cstaticstring) +- std + - async + - [async dispatch (event loop)](https://nim-lang.github.io/Nim/asyncdispatch.html) + - [async file](https://nim-lang.github.io/Nim/asyncfile.html) + - [async futures](https://nim-lang.github.io/Nim/asyncfutures.html) + - [async streams](https://nim-lang.github.io/Nim/asyncstreams.html) + - parallel + - [lock and condition vars](https://nim-lang.github.io/Nim/locks.html) + - [parallel tasks](https://nim-lang.github.io/Nim/tasks.html) + - [thread pool](https://nim-lang.github.io/Nim/threadpool.html) + - [std/typedthreads](https://github.com/nim-lang/Nim/blob/devel/lib/std/typedthreads.nim) - niche - - [co routines](https://nim-lang.org/docs/coro.html) + - [co routines](https://nim-lang.github.io/Nim/coro.html) - [fusion pools](https://nim-lang.github.io/fusion/src/fusion/pools.html) - [fusion smart pointers](https://nim-lang.github.io/fusion/src/fusion/smartptrs.html) TODOs ----- -- [passing channels safely](https://nim-lang.org/docs/channels_builtin.html#example-passing-channels-safely) -- [multiple async backend support](https://nim-lang.org/docs/asyncdispatch.html#multiple-async-backend-support) -- [add more sophisticated asyncdispatch examples](https://nim-lang.org/docs/asyncdispatch.html) +- [sys atomics](https://github.com/nim-lang/Nim/blob/devel/lib/std/sysatomics.nim) +- [system threadids](https://github.com/nim-lang/Nim/blob/devel/lib/system/threadids.nim) +- [system threadimpl](https://github.com/nim-lang/Nim/blob/devel/lib/system/threadimpl.nim) +- [thread proc body wrapper](https://nim-lang.github.io/Nim/system.html#nimThreadProcWrapperBody.t%2Cuntyped) +- [parallel and spawn](https://nim-lang.github.io/Nim/manual_experimental.html#parallel-amp-spawn-parallel-statement) +- [passing channels safely](https://nim-lang.github.io/Nim/channels_builtin.html#example-passing-channels-safely) +- [multiple async backend support](https://nim-lang.github.io/Nim/asyncdispatch.html#multiple-async-backend-support) +- [add more sophisticated asyncdispatch examples](https://nim-lang.github.io/Nim/asyncdispatch.html) - acquiring a lock for a channel is useless, locks only work with guarded vars - ^ update examples @@ -76,7 +73,6 @@ TODOs - if all CPUs are taken, timesharing occurs (concurrency semantics) ## threads - - each thread has its own GC heap and mem sharing is restricted - improves efficiency and prevents race conditions - procs used with threads require {.thread.} pragma @@ -91,9 +87,9 @@ TODOs - handled exceptions dont propagate across threads - unhandled exceptions terminates the entire process -thread vs threadpool +typedthreads vs threadpool -------------------- -- thread (system) create and save a thread to a variable +- typedthreads create and save a thread to a variable - requires manually managing the thread, its tasks, and execution - are resource intensive: only when full control is required on a limited number of threads - executes procedures but doesnt return their results @@ -109,30 +105,33 @@ thread vs threadpool - when the flowVar is fullfilled retrieve the value with ^flowVar - procedures that return a non-ref type cant be spawned -thread pragmas + +typedthreads procs +------------------ +- createThread and start execution +- destroyThread is a potentially dangerous action +- getThreadId of the currently running thread +- handle of thread +- joinThread back to main thread +- joinThreads back to main thread +- pinToCpu & set its affinity +- running true if thread is executing + +typedthread pragmas -------------- - thread: this proc is intended for multitasking - threadvar: declares this var as a threads' var - raises: should always be used to ensure a thread proc handles all its exceptions -system thread types +typedthreads types ------------------- - Thread[T] object -system thread procs -------------------- -- createThread and execute a proc on it -- getThreadId of some thread -- handle of Thread[T] -- joinThread back to main process when finished -- joinThreads back to main process when finished -- onThreadDestruction called upon threads destruction (returns/throws) -- pinToCpu sets the affinity for a thread threadpool ---------- - implements parallel & spawn -- abstraction over lower level system threads +- abstraction over lower level typedthreadss threadpool types ---------------- @@ -165,30 +164,54 @@ threadpool procs - unsafeRead a flowvar; blocks until flowvar value is available - spawnX action on new thread if CPU core ready; else on this thread; blocks produce; prefer spawn +## locks +- locks and conition vars -## channels -- designed for system.threads, unstable when used with spawn -- deeply copies non cyclic data from thread X to thread Y -- channels declared in the main thread (module scope) is simpler and shared across all threads - - else you can declare within the body of proc thread and send the ptr to another +lock types +---------- +- Cond SysCond condition variable +- Lock SysLock whether its re-entrant/not is unspecified -system channel types --------------------- -- Channel[T] for relaying messages of type T +lock procs +---------- +- acquire the given lock +- broadcast unblocks threads blocked on the specified condition variable +- deinitCond frees resources associated with condition var +- deinitLock frees resources associated with lock +- initCond initializes a condition var +- initLock intiializes a lock +- release a lock +- signal to a condition var +- tryAcquire a given lock +- wait on the condition var -system channel procs --------------------- -- close permenantly a channel and frees its resources -- open or update a channel with size int (0 == unlimited) -- peek at total messages in channel, -1 if channel closed, use tryRecv instead to avoid race conds -- ready true if some thread is waiting for new messages -- recv data; blocks its channel scope until delivered -- send deeply copied data; blocks its channel scope until sent -- tryRecv (bool, msg) -- trySend deeply copied data without blocking +lock pragmas +------------ +- guard assigns a lock to a variable, compiler throws if r/w attempts without requireing lock + +lock templates +-------------- +- withLock: acquires > executes body > releases, useful with guarded variables -## locks +## asyncdispatch +- asynchronous IO: dispatcher (event loop), future and reactor (sync-style) await +- the primary way to create and consume async programs +- dispatcher: simple event loop that buffers events to be polled (pulled) from the stack + - linux: uses epoll + - windows: IO Completion Ports + - other: select +- poll: doesnt return events, but Future[event]s when they're completed with a value/error + - always use a [reactor pattern (IMO)](https://en.wikipedia.org/wiki/Reactor_pattern) e.g. waitFor/runForever + - procs of type Future[T | void] require {.async.} pragma for enabling `await` in the body + - awaited procs are suspended until and resumed once their Future arg is completed + - the dispatcher invokes the next async proc while the current is suspended + - vars, objects and other procs can be awaited + - awaited Futures with unhandled exceptions are rethrown + - yield Future; f.failed instead of try: await Future except: for increased reliability + - alternatively (IMO not preferred) use the [proactor pattern](https://en.wikipedia.org/wiki/Proactor_pattern) + - you can check Future.finished for success/failure and .failed specifically + - or pass a callback## locks - locks and conition vars lock types @@ -343,6 +366,132 @@ asyncFutures procs - readError of a failed future - setCallSoonproc change implementation of callsoon +## asyncfile +- asynchronous reads & writes +- unlike std/os you need to get an FD on a file first via openAsync + - most procs require an AsyncFD and not a filename[string] + +asyncfile types +--------------- +- AsyncFile = ref object + - fd: AsyncFD + - offset: int64 + +asyncfile procs +--------------- +- close a file +- [get | set]File[Pos | Size] +- newAsyncFile from an AsyncFD +- openAsync file X in mode Y returning AsyncFile; all other procs require an AsyncFile +- read[All | Buffer | Line | ToStream] +- write[Buffer | FromStream] + - writeFromStream: perfect for saving streamed data to af ile without wasting memory +- addWrite/Read exist for adapting unix-like libraries to be async on windows; avoid if possible + + +asyncdispatch types +------------------- +- AsyncEvent ptr +- AsyncFD file descriptor +- Callback proc(AsyncFD) +- CompletionData object + - fd: AsyncFD + - cb: Callback + - cell: ForeignCell (system) +- CustomRef +- PDispatcher ref of PDispatcherBase + - ioPort: Handle (winlean) + - handles: HashSet[AsyncFD] + +asyncdispatch procs +------------------- +- accept new socket connection returning future client socket +- acceptAddr new socket connecting returning future (client , address) +- activeDescriptors for the current event loop (doesnt require syscall) +- addEvent registers cb to invoke upon some AsyncEvent +- addProcess registeres cb to invoke when some PID exits +- addRead starts watching AsyncFD and invokes cb when its read-ready; only useful for windows +- addTimer invokes cb after/every int milliseconds +- addWrite starts watching AsyncFD and invokes cb when its write-ready; only useful for windows +- callSoon invoke cb when control returns to the event loop +- close an AsyncEvent +- closeSocket and unregister it +- connect to socket FD at some remote addr, port and domain +- contains true if AsyncFD is registered on the current threads event loop +- createAsyncNativeSocket +- dial and connect to addr:port via some protocol (e.g. TCP for IPv4/6); tries until successful +- drain and process as many events until timeout X; errors if no events are pending +- getGlobalDispatcher +- getIoHandler for some Dispatcher; supports both win & linux +- hasPendingOperations only checks global dispatcher +- maxDescriptors of the current process (requires syscall); only for Windows, Linux, OSX, BSD +- newAsyncEvent threadsafe; not auto registered with a dispatcher +- newCustom CustomRef +- newDispatcher for this thread +- poll for X then wait to process pending events as they complete; throws ValueError if none exist +- readAll FutureStream[string] that completes when all data is consumed +- recv from socket and complete once up to/before X bytes read/socket disconnects +- recvFromInto buf of size X, datagram from socket; senders addr saved in saddr and saddrlen +- recvInto buf of size X, data from socket; completes once up to/before X bytes read/socket disconnects +- register AsyncFD with some dispatcher +- runForever the global dispatcher poll event loop +- send X bytes from buf to socket; complete once all data sent +- sendTo socket some data +- setGlobalDispatcher +- setInheritable this file descriptor by child processes; not guaranteed check with declared() +- sleepAsync for X milliseconds +- trigger AsyncEvent +- unregister AsyncEvent +- waitFor and block the current thread until Future completes +- withTimeout wait for this Future or return false if timeout expires + +asyncdispatch macros +-------------------- +- async converts async procedures into iterators and yield statements +- multisync converts async procs into both async & sync procs (removes await calls) + +## asyncfutures +- primitives for creating and consuming futures +- all other modules build on asyncfutures and generally isnt imported directly + +asyncfutures types +------------------ +- Future[T] ref of FutureBase + - value +- FutureBase ref of RootObject + - callbacks: CallbackList + - finished: bool + - error: Exception + - errorStackTrace: string +- FutureError object of Defect + - cause: FutureBase +- FutureVar[T] distinct Future[T] + +asyncfutures consts +------------------- +- isFutureLoggingEnabled + +asyncFutures procs +------------------ +- and returns future X when future Y and Z complete +- or returns future X when future Y or Z complete +- addCallback to execute when future X completes; accepts FutureBase[T]/Future[T] +- all returns when futures 0..X complete +- asyncCheck discards futures +- callsoon somecallback on next tick of asyncdispatcher if running, else immediately +- clean resets finished status of some future +- clearCallbacks +- complete future X with value Y +- fail future X with exception Y +- failed bool +- finished bool +- getCallSoonProc +- mget a mutable value stored in future +- newFuture of type T owned by proc X +- read the value of a finished future +- readError of a failed future +- setCallSoonproc change implementation of callsoon + ## asyncfile - asynchronous reads & writes - unlike std/os you need to get an FD on a file first via openAsync @@ -365,9 +514,13 @@ asyncfile procs - writeFromStream: perfect for saving streamed data to af ile without wasting memory ]## -{.push warning[UnusedImport]:off .} +{.push warning[UnusedImport]:off, hint[XDeclaredButNotUsed]: off .} import std/[sugar, strutils, strformat, locks, os] +echo "############################ typedthreads" + +import std/typedthreads + var bf: Thread[void] gf: Thread[void] @@ -375,13 +528,12 @@ var numThreads: array[4, Thread[int]] iAmGuarded {.guard: L .}: string = "require r/w to occur through my lock" -echo fmt"{iAmGuarded}" proc echoAction[T](x: T): void {.thread.} = + ## the lock needs to already be initialized ## withLock to acquire, execute & release automatically L.withLock: echo fmt"i am thread {getThreadId()=} with data {x=}" -echo "############################ system threads" L.initLock # must be initialized @@ -392,51 +544,6 @@ joinThreads(numThreads) L.deinitLock -echo "############################ system channels" - -var - relay: Channel[string] ## a queue for string data - -echo "############################ system channels: blocking" - -proc sendAction: void {.thread.} = - sleep 500 - ## action for sending data - ## blocks its channel's scope until msg delivered; deep copies its arguments - relay.send "phone ring ring ring" - -proc receiveAction: void {.thread.} = - ## action for consuming data - ## recv blocks its channel's scope until msg received - echo fmt"blocking; busy binging mr.robot: {relay.recv()=}" - echo "unblocked: until i receive data" - -open relay, maxItems = 0 ## 0 = unlimited queue - -gf.createThread sendAction -bf.createThread receiveAction -joinThreads gf, bf - -echo "############################ channels: non blocking" - -proc sendActionA: void {.thread.} = - ## action for sending data without blocking - sleep 500 - ## deep copies its arguments - if not relay.trySend "phone ring ring ring": echo "failed to send message" - -proc receiveActionA: void {.thread.} = - ## action for consuming data without blocking - while true: - let comms = relay.tryRecv() - if comms.dataAvailable: echo fmt"non blocking: {comms.msg=}"; break - echo "never blocked: no data!" - sleep 400 ## before next check - -gf.createThread sendActionA -bf.createThread receiveActionA -joinThreads gf, bf - echo "############################ threadpool" import std/threadpool @@ -445,18 +552,6 @@ for i in numThreads.low .. numThreads.high: sync() ## join created actors to main thread -## adjust channel size capping at 1 message -open relay, 1 - -spawn sendAction() -spawn sendActionA() ## unsuccessful because total msg > channel size 1 -spawn sendActionA() -spawn receiveActionA() -sync() - -close relay - - echo "############################ asyncdispatch " import std/[asyncdispatch] @@ -477,7 +572,7 @@ proc f2 (): Future[string] {.async.} = try: await sleepAsync(1) result = "try/catch wont catch all async errors all the time" - except: + except CatchableError: result = "exception was thrown" echo fmt"{waitFor f2()=}" @@ -533,17 +628,18 @@ const try: afilepath.parentDir.createDir discard fmt"touch {afilepath}".execShellCmd -except: echo fmt"couldnt create {afilepath.parentDir}" +except CatchableError: echo fmt"couldnt create {afilepath.parentDir}" -var - reader = afilepath.openAsync fmRead - writer = afilepath.openAsync fmWrite +# TODO(noah): fmRead and fmWrite dont exist +# var +# reader = afilepath.openAsync fmRead +# writer = afilepath.openAsync fmWrite -waitFor writer.write "first line in file\n" -let cursize = writer.getFileSize -echo fmt"{waitFor reader.read (int)cursize=}" -waitFor writer.write "second line in file" -echo fmt"{waitFor reader.read (int)writer.getFileSize - cursize=}" +# waitFor writer.write "first line in file\n" +# let cursize = writer.getFileSize +# echo fmt"{waitFor reader.read (int)cursize=}" +# waitFor writer.write "second line in file" +# echo fmt"{waitFor reader.read (int)writer.getFileSize - cursize=}" -for f in [reader,writer]: f.close +# for f in [reader,writer]: f.close diff --git a/src/bookofnim/deepdives/collections.nim b/src/bookofnim/deepdives/collections.nim index a909bb7b..99782b5a 100644 --- a/src/bookofnim/deepdives/collections.nim +++ b/src/bookofnim/deepdives/collections.nim @@ -1,7 +1,7 @@ ## ## collections deep dive ## ===================== -## [bookmark](https://nim-lang.org/docs/packedsets.html) +## [bookmark](https://nim-lang.github.io/Nim/packedsets.html) ##[ ## TLDR @@ -14,16 +14,16 @@ - other - [peter: option handling in nim](https://peterme.net/optional-value-handling-in-nim.html) - high impact - - [critbits sorted strings](https://nim-lang.org/docs/critbits.html) - - [int sets](https://nim-lang.org/docs/intsets.html) - - [options](https://nim-lang.org/docs/options.html) - - [ordered +/ hash sets](https://nim-lang.org/docs/sets.html) - - [packed (sparse bit) sets](https://nim-lang.org/docs/packedsets.html) - - [seq (seq, strings, array) utils](https://nim-lang.org/docs/sequtils.html) - - [set utils](https://nim-lang.org/docs/setutils.html) + - [critbits sorted strings](https://nim-lang.github.io/Nim/critbits.html) + - [int sets](https://nim-lang.github.io/Nim/intsets.html) + - [options](https://nim-lang.github.io/Nim/options.html) + - [ordered +/ hash sets](https://nim-lang.github.io/Nim/sets.html) + - [packed (sparse bit) sets](https://nim-lang.github.io/Nim/packedsets.html) + - [seq (seq, strings, array) utils](https://nim-lang.github.io/Nim/sequtils.html) + - [set utils](https://nim-lang.github.io/Nim/setutils.html) - niche - [fusion pointers](https://nim-lang.github.io/fusion/src/fusion/pointers.html) - - [fixed length runtime arrays](https://nim-lang.org/docs/rtarrays.html) + - [fixed length runtime arrays](https://nim-lang.github.io/Nim/rtarrays.html) ## seqs - toSeq(blah) transforms any iterable into a sequence @@ -97,7 +97,7 @@ options operators - == true if both are none/equal values ]## -{.push hint[XDeclaredButNotUsed]: off .} +{.push hint[XDeclaredButNotUsed]:off, warning[UnusedImport]:off .} import std/[sugar, strformat] @@ -146,26 +146,28 @@ proc echoMutated(): void = echo "seq: ", $mutable, "str: ", $mutated echoMutated() -mutable.apply x => x * x; echoMutated() ## \ - ## mutates its operand -mutable.apply x => mutated.addInt x; echoMutated() ## \ - ## mutates the string instead -mutable.delete 2..3; echoMutated() ## \ - ## inclusive from..to -mutable.insert @[3,2,1], 1; echoMutated() ## \ - ## default is to unshift at 0 and can be omitted +mutable.apply x => x * x; echoMutated() + # mutates its operand +mutable.apply x => mutated.addInt x; echoMutated() + # mutates the string instead +mutable.delete 2..3; echoMutated() + # inclusive from..to +mutable.insert @[3,2,1], 1; echoMutated() + # default is to unshift at 0 and can be omitted mutable.keepIf x => x > 0; echoMutated() echo "############################ sets" import std/sets const - stringSet1 = toHashSet ["ay", "bee", "see", "dee"] ## string|array|seq - stringSet2 = toHashSet ["dee","ee", "ehf", "gee", "aych"] floatSet = toOrderedSet [1.0, 3.0, 2.0, 4.0] + stringSet2 = toHashSet ["dee","ee", "ehf", "gee", "aych"] + stringSet1 = toHashSet(["ay", "bee", "see", "dee"]) + ## string|array|seq < figure out which of the above this belongs to echo "############################ sets pure" + echo fmt"alias for intersection {stringset1 * stringset2=}" echo fmt"alias for union {stringset1 + stringset2=}" echo fmt"alias for symmetricDifference {stringset1 -+- stringset2=}" @@ -214,6 +216,7 @@ echo fmt"{toSeq(sortedStringSet.keys)=}" echo "############################ critbits dict" + let sortedStringDict: CritBitTree[int] = {"zfirst": 1, "asecond": 2}.toCritBitTree echo fmt"{sortedStringDict=}" @@ -229,11 +232,10 @@ echo "############################ options" import std/options const something = (x: string) => (if x == "thing": some("some" & x) else: none(string)) ## \ - ## converts a thing to something const maybe = some("thing") ## optional string - nothing = none(string) ## optional string + nothing = none(string) echo fmt"{maybe=}" echo fmt"{nothing.isNone=}" diff --git a/src/bookofnim/deepdives/containers.nim b/src/bookofnim/deepdives/containers.nim index b09ba9c1..f95f795a 100644 --- a/src/bookofnim/deepdives/containers.nim +++ b/src/bookofnim/deepdives/containers.nim @@ -5,7 +5,7 @@ ##[ ## TLDR -- [custom types as keys require hash + == procs](https://nim-lang.org/docs/tables.html#basic-usage-hashing) +- [custom types as keys require hash + == procs](https://nim-lang.github.io/Nim/tables.html#basic-usage-hashing) - generally all table types have the same interface; CountTables a bit more - critbit can be used as a sorted string dictionary - system.table is often used to collect and convert literals into std/tables @@ -13,12 +13,12 @@ links ----- - high impact - - [tables: hash](https://nim-lang.org/docs/tables.html) - - [tables: string](https://nim-lang.org/docs/strtabs.html) + - [tables: hash](https://nim-lang.github.io/Nim/tables.html) + - [tables: string](https://nim-lang.github.io/Nim/strtabs.html) - [tables: fusion btree](https://nim-lang.github.io/fusion/src/fusion/btreetables.html) - niche - - [enum utils](https://nim-lang.org/docs/enumutils.html) - - [shared tables](https://nim-lang.org/docs/sharedtables.html) + - [enum utils](https://nim-lang.github.io/Nim/enumutils.html) + - [shared tables](https://nim-lang.github.io/Nim/sharedtables.html) TODOs ----- @@ -140,17 +140,18 @@ let u = User(name: "Hello", uid: 99) t[1] = u t.withValue(1, value): - ## block is executed only if `key` in `t` - ## to modify value it must be a ref/ptr + # block is executed only if t has key 1 + # to modify value it must be a ref/ptr, which User is value.name = "Nim" value.uid = 1314 +from std/assertions import doAssert t.withValue(521, value): doAssert false do: # block is executed when `key` not in `t` t[1314] = User(name: "exist", uid: 521) - +echo fmt"{t[1314].name=}" echo "############################ strtabs" # len, keys, pairs, values @@ -161,7 +162,7 @@ let authnz = { "ROLE": "USER", "TRUSTED": "0", - }.newStringTable modeCaseSensitive ## \ + }.newStringTable modeCaseSensitive ## also accepts a tuple[varargs] of keyX,valY, ... echo fmt"{authnz.mode=}" @@ -194,4 +195,5 @@ proc hash(x: User): Hash = !$x.uid.hash var userDictionary = initTable[User, string]() userDictionary[User(name: "noah", uid: 1234)] = "custom keys!" -echo fmt"{userDictionary=}" +# TODO(noah): requires overloading $ for userDictionary? +# echo fmt"{userDictionary=}" diff --git a/src/bookofnim/deepdives/crypto.nim b/src/bookofnim/deepdives/crypto.nim index 0010b3a1..c8591446 100644 --- a/src/bookofnim/deepdives/crypto.nim +++ b/src/bookofnim/deepdives/crypto.nim @@ -1,7 +1,7 @@ ## ## cryptography ## ============ -## [bookmark](https://nim-lang.org/docs/sha1.html) +## [bookmark](https://nim-lang.github.io/Nim/sha1.html) ##[ ## TLDR @@ -19,17 +19,17 @@ links - other - before using any nim hashing fn: [read this](https://github.com/nim-lang/Nim/issues/19863) - high impact - - [base64 en/decoder](https://nim-lang.org/docs/base64.html) - - [efficient 1way hashing](https://nim-lang.org/docs/hashes.html) - - [globally distributed unique IDs](https://nim-lang.org/docs/oids.html) - - [md5 checksums](https://nim-lang.org/docs/md5.html) - - [openssl](https://nim-lang.org/docs/openssl.html) - - [random number generator](https://nim-lang.org/docs/random.html) - - [random sys number generator](https://nim-lang.org/docs/sysrand.html) - - [sha-1](https://nim-lang.org/docs/sha1.html) - - [ssl cert finder](https://nim-lang.org/docs/ssl_certs.html) + - [base64 en/decoder](https://nim-lang.github.io/Nim/base64.html) + - [efficient 1way hashing](https://nim-lang.github.io/Nim/hashes.html) + - [globally distributed unique IDs](https://nim-lang.github.io/Nim/oids.html) + - [md5 checksums](https://nim-lang.github.io/Nim/md5.html) + - [openssl](https://nim-lang.github.io/Nim/openssl.html) + - [random number generator](https://nim-lang.github.io/Nim/random.html) + - [random sys number generator](https://nim-lang.github.io/Nim/sysrand.html) + - [sha-1](https://nim-lang.github.io/Nim/sha1.html) + - [ssl cert finder](https://nim-lang.github.io/Nim/ssl_certs.html) - nitche - - [mersenne](https://nim-lang.org/docs/mersenne.html) + - [mersenne](https://nim-lang.github.io/Nim/mersenne.html) ## ssl_certs @@ -106,5 +106,7 @@ import std/base64 echo fmt"{myString.encode=}" echo fmt"{myString.encode.decode=}" -echo fmt"{encode $objectSome=}" -echo fmt"{decode encode $objectSome=}" + +# TODO(noah): think requires overloading +# echo fmt"{encode $objectSome=}" +# echo fmt"{decode encode $objectSome=}" diff --git a/src/bookofnim/deepdives/data.nim b/src/bookofnim/deepdives/data.nim index e2bce1d3..b5b77d9f 100644 --- a/src/bookofnim/deepdives/data.nim +++ b/src/bookofnim/deepdives/data.nim @@ -1,7 +1,7 @@ ## ## working with data ## ================= -## [bookmark](https://nim-lang.org/docs/logging.html) +## [bookmark](https://nim-lang.github.io/Nim/logging.html) ##[ TLDR @@ -13,23 +13,23 @@ TLDR links ----- - high impact - - [csv parser](https://nim-lang.org/docs/parsecsv.html) - - [json utils](https://nim-lang.org/docs/jsonutils.html) - - [json](https://nim-lang.org/docs/json.html) - - [logging](https://nim-lang.org/docs/logging.html) - - [marshal](https://nim-lang.org/docs/marshal.html) + - [csv parser](https://nim-lang.github.io/Nim/parsecsv.html) + - [json utils](https://nim-lang.github.io/Nim/jsonutils.html) + - [json](https://nim-lang.github.io/Nim/json.html) + - [logging](https://nim-lang.github.io/Nim/logging.html) + - [marshal](https://nim-lang.github.io/Nim/marshal.html) - niche - - [base object of a lexer](https://nim-lang.org/docs/lexbase.html) + - [base object of a lexer](https://nim-lang.github.io/Nim/lexbase.html) - [fusion ht/xml parser](https://nim-lang.github.io/fusion/src/fusion/htmlparser/parsexml.html) - [fusion ht/xml tree](https://nim-lang.github.io/fusion/src/fusion/htmlparser/xmltree.html) - [fusion htmlparser](https://nim-lang.github.io/fusion/src/fusion/htmlparser.html) - - [ht/xml parser](https://nim-lang.org/docs/xmlparser.html) - - [ht/xml tree](https://nim-lang.org/docs/xmltree.html) - - [ht/xml](https://nim-lang.org/docs/parsexml.html) - - [html generator](https://nim-lang.org/docs/htmlgen.html) - - [html parser](https://nim-lang.org/docs/htmlparser.html) - - [json parser](https://nim-lang.org/docs/parsejson.html) - - [var ints](https://nim-lang.org/docs/varints.html) + - [ht/xml parser](https://nim-lang.github.io/Nim/xmlparser.html) + - [ht/xml tree](https://nim-lang.github.io/Nim/xmltree.html) + - [ht/xml](https://nim-lang.github.io/Nim/parsexml.html) + - [html generator](https://nim-lang.github.io/Nim/htmlgen.html) + - [html parser](https://nim-lang.github.io/Nim/htmlparser.html) + - [json parser](https://nim-lang.github.io/Nim/parsejson.html) + - [var ints](https://nim-lang.github.io/Nim/varints.html) ## json @@ -98,7 +98,11 @@ jsonutils procs ]## # styleCheck complains about capitulation of http headers -{.push hint[Name]:off, warning[UnusedImport]:off .} +{.push + hint[Name]:off, + warning[UnusedImport]:off, + hint[XDeclaredButNotUsed]:off +.} import std/[sugar, strformat, strutils, sequtils, options, tables] @@ -142,7 +146,7 @@ let echo fmt"{resJson.pretty=}""" echo fmt"{resJson.kind=}" echo fmt"{resJson=}" -echo fmt"{resType=}" +# echo fmt"{resType=}" TODO(noah): throws in v2 echo fmt"{resJson.hash=}" echo fmt"""{resJson.hasKey "body"=}""" echo fmt"""{resJson.contains "body"=}""" @@ -159,7 +163,7 @@ echo fmt"""{resJson["headers"]["Status"].getInt=}""" echo fmt"""{resJson\{"headers","Status"\}.getInt=}""" echo fmt"""{resJson["headers"]["Host"].copy=}""" -echo fmt"""curlies return default value {resJson\{"doesntexist"\}.getFloat=}""" +# echo fmt"""curlies return default value {resJson\{"doesntexist"\}.getFloat=}""" # TODO(noah): throws in v2 echo fmt"""e.g. empty string {resJson["headers"]\{"X-Vault-Token"\}.getStr=}""" echo fmt"""{"string to json + quotes".escapeJson=}""" echo fmt"""{"string to json - quotes".escapeJsonUnquoted=}""" @@ -168,7 +172,7 @@ echo "############################ json impure" # toUgly is faster than pretty/$ but requires a var var - reqData = %* { "tupac": {"quotes": ["dreams are for real"]}} ## \ + reqData = %* { "tupac": {"quotes": ["dreams are for real"]}} ## dynamic: instantiate json node proc echoReqData: void = echo fmt"{reqData=}" @@ -201,9 +205,9 @@ t.fromJsonHook parseJson """{ }""" ## inplace version of jsonTo echo fmt"t.fromJsonHook(parseJson(string)) -> {t=}" -const opts = Joptions(allowExtraKeys: true, allowMissingKeys: true) ## \ +const opts = Joptions(allowExtraKeys: true, allowMissingKeys: true) ## more succcint than the strtab example -echo fmt"{resJson.jsonTo(ResponseType, opts)=}" +# echo fmt"{resJson.jsonTo(ResponseType, opts)=}" # TODO(noah): throws in v2 echo fmt"{some(1).toJson=}" echo fmt"{none[int]().toJson=}" diff --git a/src/bookofnim/deepdives/dataWrangling.nim b/src/bookofnim/deepdives/dataWrangling.nim index 43af6048..c07a8a91 100644 --- a/src/bookofnim/deepdives/dataWrangling.nim +++ b/src/bookofnim/deepdives/dataWrangling.nim @@ -1,7 +1,7 @@ ## ## data wrangling ## ============== -## [bookmark](https://nim-lang.org/docs/strscans.html) +## [bookmark](https://nim-lang.github.io/Nim/strscans.html) ##[ TLDR @@ -24,13 +24,13 @@ links - examples - [nimgrep source code](https://github.com/nim-lang/Nim/blob/devel/tools/nimgrep.nim) - high impact - - [peg matching](https://nim-lang.org/docs/pegs.html) - - [regex pcre wrapper](https://nim-lang.org/docs/re.html) - - [string scans](https://nim-lang.org/docs/strscans.html) + - [peg matching](https://nim-lang.github.io/Nim/pegs.html) + - [regex pcre wrapper](https://nim-lang.github.io/Nim/re.html) + - [string scans](https://nim-lang.github.io/Nim/strscans.html) - [fusion matching](https://nim-lang.github.io/fusion/src/fusion/matching.html) - - [parse utils](https://nim-lang.org/docs/parseutils.html) + - [parse utils](https://nim-lang.github.io/Nim/parseutils.html) - nitche - - [perl compatible regex](https://nim-lang.org/docs/pcre.html) + - [perl compatible regex](https://nim-lang.github.io/Nim/pcre.html) TODOs ----- diff --git a/src/bookofnim/v2/dataWranglingV2.nim b/src/bookofnim/deepdives/dataWranglingV2.nim similarity index 100% rename from src/bookofnim/v2/dataWranglingV2.nim rename to src/bookofnim/deepdives/dataWranglingV2.nim diff --git a/src/bookofnim/deepdives/datetime.nim b/src/bookofnim/deepdives/datetime.nim index 02bf089f..8fd15a2c 100644 --- a/src/bookofnim/deepdives/datetime.nim +++ b/src/bookofnim/deepdives/datetime.nim @@ -1,7 +1,7 @@ ## ## datetime ## ======== -## [bookmark](https://nim-lang.org/docs/monotimes.html) +## [bookmark](https://nim-lang.github.io/Nim/monotimes.html) ##[ ## TLDR @@ -19,8 +19,8 @@ links ----- -- [date & times](https://nim-lang.org/docs/times.html) -- [mono times](https://nim-lang.org/docs/monotimes.html) +- [date & times](https://nim-lang.github.io/Nim/times.html) +- [mono times](https://nim-lang.github.io/Nim/monotimes.html) - [timezone names, but any unambiguous string can be used](https://en.wikipedia.org/wiki/Tz_database) TODOs @@ -177,13 +177,14 @@ echo fmt"epoch Time {$fromUnixFloat(0)=}" echo fmt"epoch Time {$fromUnix(0)=}" echo fmt"epoch Time {$fromUnix(0).utc=}" echo fmt"epoch {$initTime(0,0)=}" -echo fmt"epoch {epochTime()=}" +# echo fmt"epoch {epochTime()=}" # TODO(noah): throws in v2 echo fmt"{getTime().utc + 1.hours=}" echo fmt"{$bday.utcOffset=}" echo fmt"{$bday.toTime=}" -echo fmt"{$bday.toTime.toUnix=}" ## time since epoch -echo fmt"${bday.toTime.toUnixFloat=}" ## same but using subsecond resolution -echo fmt"{$bday.weekday=}" ## any dt unit (see above) +echo fmt"{$bday.toTime.toUnix=}" # time since epoch +# TODO(noah): throws in v2 +# echo fmt"${bday.toTime.toUnixFloat=}" # same but using subsecond resolution +echo fmt"{$bday.weekday=}" # any dt unit (see above) echo fmt"""{bday.format "YYYY'/'MMM' at 'htt"=}""" echo fmt"""string to date {"1969-01-01".parse(fdate)=}""" echo fmt"""string to formatted date {"1969-01-01".parse(fdate).format(fdate)=}""" diff --git a/src/bookofnim/deepdives/ffi.nim b/src/bookofnim/deepdives/ffi.nim index cf50cde4..da5c8755 100644 --- a/src/bookofnim/deepdives/ffi.nim +++ b/src/bookofnim/deepdives/ffi.nim @@ -7,9 +7,10 @@ links ----- - [native python integration](https://github.com/yglukhov/nimpy) +- [Foreign function interface](https://nim-lang.github.io/Nim/manual.html#foreign-function-interface) TODOs ----- - niminaction chapter 8 -- import in bookofnim and add to readme + ]## diff --git a/src/bookofnim/deepdives/filters.nim b/src/bookofnim/deepdives/filters.nim index bfc25b31..8e564e91 100644 --- a/src/bookofnim/deepdives/filters.nim +++ b/src/bookofnim/deepdives/filters.nim @@ -1,7 +1,7 @@ ## ## filters ## ======= -## [bookmark](https://nim-lang.org/docs/asyncstreams.html) +## [bookmark](https://nim-lang.github.io/Nim/asyncstreams.html) ##[ ## TLDR @@ -9,6 +9,6 @@ TODO ---- -- [filters](https://nim-lang.org/docs/filters.html) +- [filters](https://nim-lang.github.io/Nim/filters.html) - niminaction: 200 -> 210 ]## diff --git a/src/bookofnim/deepdives/lists.nim b/src/bookofnim/deepdives/lists.nim index c5cf989e..fc7685a0 100644 --- a/src/bookofnim/deepdives/lists.nim +++ b/src/bookofnim/deepdives/lists.nim @@ -1,7 +1,7 @@ ## ## lists ## ===== -## [bookmark](https://nim-lang.org/docs/lists.html) +## [bookmark](https://nim-lang.github.io/Nim/lists.html) ##[ ## TLDR @@ -10,11 +10,11 @@ links ----- - high impact - - [singly/doubly linked list/rings](https://nim-lang.org/docs/lists.html) - - [double ended queue](https://nim-lang.org/docs/deques.html) - - [heapqueue](https://nim-lang.org/docs/heapqueue.html) + - [singly/doubly linked list/rings](https://nim-lang.github.io/Nim/lists.html) + - [double ended queue](https://nim-lang.github.io/Nim/deques.html) + - [heapqueue](https://nim-lang.github.io/Nim/heapqueue.html) - niche - - [shared list](https://nim-lang.org/docs/sharedlist.html) + - [shared list](https://nim-lang.github.io/Nim/sharedlist.html) list procs diff --git a/src/bookofnim/deepdives/maths.nim b/src/bookofnim/deepdives/maths.nim index 371c0208..5c110872 100644 --- a/src/bookofnim/deepdives/maths.nim +++ b/src/bookofnim/deepdives/maths.nim @@ -1,7 +1,7 @@ ## ## maths ## ===== -## [bookmark](https://nim-lang.org/docs/math.html) +## [bookmark](https://nim-lang.github.io/Nim/math.html) ##[ ## TLDR @@ -10,13 +10,13 @@ links ----- - high impact - - [basic math](https://nim-lang.org/docs/math.html) - - [rational numbers](https://nim-lang.org/docs/rationals.html) - - [statistical analysis](https://nim-lang.org/docs/stats.html) + - [basic math](https://nim-lang.github.io/Nim/math.html) + - [rational numbers](https://nim-lang.github.io/Nim/rationals.html) + - [statistical analysis](https://nim-lang.github.io/Nim/stats.html) - niche - - [complex numbers](https://nim-lang.org/docs/complex.html) - - [floating point env](https://nim-lang.org/docs/fenv.html) - - [summation functions](https://nim-lang.org/docs/sums.html) + - [complex numbers](https://nim-lang.github.io/Nim/complex.html) + - [floating point env](https://nim-lang.github.io/Nim/fenv.html) + - [summation functions](https://nim-lang.github.io/Nim/sums.html) system procs ------------ diff --git a/src/bookofnim/deepdives/memoryCompiler.nim b/src/bookofnim/deepdives/memoryCompiler.nim index c6952f37..20048861 100644 --- a/src/bookofnim/deepdives/memoryCompiler.nim +++ b/src/bookofnim/deepdives/memoryCompiler.nim @@ -1,58 +1,43 @@ ## -## memory GC and compiler -## ====================== -## bookmark: rework this entire file +## memory mgmt and compiler +## ======================== +## [bmark: everything starting here](https://nim-lang.github.io/Nim/nimc.html#crossminuscompilation) ##[ ## TLDR -- Stack allocated (value semantics) - - plain objects - - chars - - numbers - - pointer types (alloc) -- Heap allocated (usually ref semantics) - - sequences (value semantics) - - strings (value semantics) - - ref types - - pointer types (malloc) -- Copied on assignment - - sequences - - strings -- mutable - - var (variables & parameters) - - ref/pointer types can always be mutated through a pointer -- immutable - - const (compile time) - - let (runtime, cant be reassigned) - - ref/pointer variables cant point to a new ref/pointer after - +- newruntime in docs refer to orc/arc, and is deprecated in favor of picking one of orc/arc +- ORC: the default memory management strategy + - abc +- ARC + - abc +- REFC: reference counting + - nim < 2 default stratetgy links ----- - other - - [chris: understanding mmap (video)](https://www.youtube.com/watch?v=8hVLcyBkSXY) - - [memory mgmt intro](https://nimbus.guide/auditors-book/02.2.3_memory_management_gc.html) + - [nimbus memory mgmt intro](https://nimbus.guide/auditors-book/02.2.3_memory_management_gc.html) - [advanced compilers self guided online course](https://www.cs.cornell.edu/courses/cs6120/2020fa/self-guided/) + - [a cost model for nim](https://nim-lang.org/blog/2022/11/11/a-cost-model-for-nim.html)\ + - [introduct to arc/orc](https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc-in-nim.html) - high impact docs - - [backend introduction](https://nim-lang.org/docs/backends.html) - - [cross compile applications](https://nim-lang.org/docs/nimc.html#crossminuscompilation) - - [destructors and move symantics](https://nim-lang.org/docs/destructors.html) - - [gc docs](https://nim-lang.org/1.6.0/gc.html) - - [memory management](https://nim-lang.org/docs/mm.html) - - [nim compiler](https://nim-lang.org/docs/nimc.html) -- source - - abc + - [backend introduction](https://nim-lang.github.io/Nim/backends.html) + - [cross compile applications](https://nim-lang.github.io/Nim/nimc.html#crossminuscompilation) + - [destructors and move symantics](https://nim-lang.github.io/Nim/destructors.html) + - [memory management](https://nim-lang.github.io/Nim/mm.html) + - [nim compiler](https://nim-lang.github.io/Nim/nimc.html) + TODOs ----- - niminaction: appendix b 282-290 - [checkout glmf example repo for targeting android/ios](https://github.com/treeform/glfm) - review this entire file again, shiz alot clearer now -- useStdoutAsStdmsg @see https://nim-lang.org/docs/io.html#stdmsg.t +- useStdoutAsStdmsg @see https://nim-lang.github.io/Nim/io.html#stdmsg.t - Mixed mode projects are not officially supported anymore, it's too hard - [forum conversation](https://forum.nim-lang.org/t/9948) - [embedded stack trace profiler guide](https://nim-lang.org/1.6.10/estp.html) -- [additional features](https://nim-lang.org/docs/nimc.html#additional-features) +- [additional features](https://nim-lang.github.io/Nim/nimc.html#additional-features) - [compiling nim with PGO post](https://forum.nim-lang.org/t/10128) ## nimc @@ -60,122 +45,154 @@ TODOs - nim --fullhelp see all cmd line opts - nim --listCmd -CMDS ----- -- buildIndex build index for all docs +path substitution +----------------- +- $nim: the global nim prefix path +- $lib: the stdlib path +- $home and ~: users home path +- $config: the main file being compiled +- $projectname: the main file without the ext +- $project[path/dir]: the main files path +- $nimcache: think this is always nimble's cache dir + +configuration file hierarchy & precedence +----------------------------------------- +- file.nim passed to compile/run becomes the $project file name +- later files overwrite previous settings +- any OPT in this file can be specified in a cfg file; same format as cmd line args +- cmd line opts > cfg file opts + - install dirs: $nim/config/nim.cfg > etc/nim/nim.cfg [nix] | /config/nim.cfg [win] + - user dirs: $XDG_CONFIG_HOME/nim/nim.cfg | ~/.config/nim/nim.cfg [nix] | %APPDATA%/nim/nim.cfg [win] + - recursive parent dirs: $parentDir/nim.cfg all the way to root + - project dir: $projectDir/nim.cfg lives next to the $project file + - project cfg file: $projectDir/$project.nim.cfg + +## nimc CMDS + +high impact cmds +---------------- - check for syntax/semantics -- compile/c -- compileToC/cc c backend -- compileToCpp/cpp c++ backend -- compileToOC/objc objective c backend -- ctags create tags file +- compile to --backend:thisThing by default uses -c +- compileToC/cc specifically to C +- compileToCpp/cpp specifically c++ backend +- compileToOC/objc specifically objective c backend - doc generate documentation for a specific backend -- dump list conditions & search paths - e run a nimscript file (file.nims not file.nim) +- js specifically javascript backend +- md2html convert a markdown file to html +- r compile to $nimcache/projectname then run it, prefer this over `c -r` +- rst2html convert an rst file to html + +useful cmds +----------- +- dump list conditions & search paths + +niche cmds +---------- +- buildIndex build index for all docs +- ctags create tags file - genDepend output dependency graph to a dot file -- js javascript backend - jsondoc output docs to a json file -- r compile to $nimcache/projectname then run it, prefer this over `c -r` -compiler OPTS -------------- -- --app:console/gui/lib/staticlib generate a console app|GUI app|DLL|static library -- --backend/-b:c|cpp|js|objc backend to use with commands like nim doc or nim r +## compiler OPTS +- these options are set by either `--blah` or `define:blah` + - 99% of these should be set in a config.nims +- specifically for those using --define syntax + - case and _ insensitive + - values can be checked in when, defined(), and {.define.} pragmas + - keys starting with nim are reserved +- opts provided on the CMD line >>> opts in config files +- @see https://nim-lang.github.io/Nim/nimc.html#compiler-usage-compileminustime-symbols +- @see https://nim-lang.github.io/Nim/manual.html#implementation-specific-pragmas-compileminustime-define-pragmas +- @see https://nim-lang.github.io/Nim/nimc.html#crossminuscompilation + +high impact OPTS lvl 1 +---------------------- +- --debugger:native use native gdb debugger +- --define:danger remove all runtime checks and debugging, e.g. benchmarks against C +- --define:release optimize for performance (default is debug) +- --define:ssl activate OpenSSL ssl sockets module +- --forceBuild/-f:on/off rebuild all modules +- --multimethods:on|off +- --opt:none/speed/size e.g. small output size (IoT), or fast runtime +- --out/-o:FILE change the output filename +- --outdir:DIR change the output dir +- --panics:on|off turn panics into process terminations +- --putenv:key=value +- --styleCheck:off|hint|error hints or errors for identifiers conflicting with official style guide +- --styleCheck:usages enforce consistent spellings of identifiers, but not style declarations +- --undefine a symbol set by --define +- --useRealtimeGC enable nims GC for solf realtime systems + +high impact OPTS lvl 2 +------------------------------------- +- --assertions/-a:on/off TODO(noah): done think this is relevant for v2 - --checks/-x:on/off turn all runtime checks on|off -- --colors:on|off for compiler msgs +- --deepcopy:on|off 'system.deepCopy', required to set via cli if using with --mm:arc|orc +- --define:nimMaxDescriptorsFallback=N for httpasyncserver +- --define:nimStrictDelete throws if indexed passed to a delete operator is out of bounds - --errorMax:N stop compilation after N errors; 0 means unlimited -- --exceptions:setjmp|cpp|goto|quirky exception handling implementation +- --excessiveStackTrace:on|off stack traces use full file paths - --experimental:$1 enable experimental language feature X -- --hotCodeReloading:on|off support for hot code reloading on|off - --implicitStatic:on|off implicit compile time evaluation on|off -- --incremental:on|off only recompile the changed modules -- --deepcopy:on|off 'system.deepCopy', required to set via cli if using with --mm:arc|orc -- --mm:orc|arc|refc|markAndSweep|boehm|go|none|regions memory mgmt strategy, orc for new/async, arc|orc for realtime systems -- --multimethods:on|off -- --panics:on|off turn panics into process terminations - --parallelBuild:N num of cpus for parallel build (0 for auto-detect) -- --sinkInference:on|off turn sink parameter inference on|off -- --threads:on enable mult-threading +- --showAllMismatches:on|off in overloading resolution +- --spellSuggest|:num|auto just set to `--spellSugest` and move on with life +- --threads:on enable mult-threading (defaults to on) - --tlsEmulation:on|off thread local storage emulation -- --trmacros:on|off term rewriting macros - --verbosity:0|1|2|3 0 minimal, 1 default, 2 stats/libs/filters, 3 debug for compiler developers -compile time symbol/switches OPTS ---------------------------------- -- values can be checked in when, defined(), and define pragmas -- case and _ insensitive -- keys starting with nim are reserved -- @see https://nim-lang.org/docs/nimc.html#compiler-usage-compileminustime-symbols -- either --define/-d:woop[=soop] - - --define:danger remove all runtime checks and debugging, e.g. benchmarks against C - - --define:release optimize for performance (default is debug) - - --define:ssl activate OpenSSL ssl sockets module - - --define:useMalloc optimize for low memory systems using C's malloc instead of Nim's memory manager, requires --mm:none/arc/orc, also see nimPage256/516/1k & nimMemAlignTiny - - --define:useRealtimeGC support for soft realtime systems - - --define:logGC gc logging to stdout - - --define:nodejs target nodejs (not web) when target is js - - --define:memProfiler memory profile for the native GC - - --define:uClibc use uClibc instead of libc - - --define:nimStrictDelete throws if indexed passed to a delete operator is out of bounds - - --define:tempDir=woop override path returned in os.getTempDir() - -output OPTS +useful OPTS ----------- -- --asm produce assembler code -- --assertions/-a:on/off -- --embedsrc:on|off embeds the original source code as comments in the generated output -- --forceBuild/-f:on/off rebuild all modules -- --index:on|off index file generation +- --clearNimblePath empty the list of Nimble package search paths +- --define:tempDir=woop override path returned in os.getTempDir() +- --hotCodeReloading:on|off support for hot code reloading on|off +- --import:PATH a module before compiling/running +- --include:PATH a module before compiling/running +- --incremental:on|off only recompile the changed modules +- --lib:PATH set system library path - --lineDir:on|off runtime stacktraces include #line directives C only with --native:debugger - --lineTrace:on/off runtime stacktraces include line numbers C only +- --NimblePath:PATH add a path for Nimble support - --nimcache:PATH generated files, ($XDG_CACHE_HOME|~/.cache)/nim/$projectname(_r|_d) useful for isolating/immutable/deleting built files - --nimMainPrefix:prefix use {prefix}NimMain instead of NimMain in the produced C/C++ code -- --noLinking:on|off compile Nim and generated files but do not link -- --opt:none/speed/size e.g. small output size (IoT), or fast runtime -- --out/-o:FILE change the output filename -- --outdir:DIR change the output dir -- --stackTrace:on/off runtime stacktrackes C only +- --noNimblePath deactivate the Nimble path +- --path/-p:PATH add path to search paths -cross compilation OPTS ----------------------- -- @see https://nim-lang.org/docs/nimc.html#crossminuscompilation-for-windows (then scroll down for other targets) + +backend/targeting/cross-compiling OPTS +-------------------------------------- +- --app:console/gui/lib/staticlib generate a console app|GUI app|DLL|static library +- --asm produce assembler code +- --backend/-b:c|cpp|js|objc backend to use with commands like nim doc or nim r - --cc:llvm_gcc|etc specify the C compiler, use --forceBuild to switch between compilers - --compileOnly/-c:on|off compile nim and generate .dep files, but do not link - --cpu:arm|i386|etc set the target processor, grep hostCPU for values +- --define:nodejs target nodejs (not web) when target is js +- --define:uClibc use uClibc instead of libc +- --embedsrc:on|off embeds the original source code as comments in the generated output - --genScript:on|off generates a compile script, forces --compileOnly +- --jsbigint64:on|off enable BigInt 64bit integers for js (defaults on) +- --noLinking:on|off compile Nim and generated files but do not link - --noMain:on|off do not generate a main procedure (required for some targets) - --os:any|linux|android|ios|nintendoswitch the target operating system, grep hostOS for values +- --stackTrace:on/off runtime stacktrackes C only -path OPTS ---------- -- --clearNimblePath empty the list of Nimble package search paths -- --import:PATH a module before compiling/running -- --include:PATH a module before compiling/running -- --lib:PATH set system library path -- --NimblePath:PATH add a path for Nimble support -- --noNimblePath deactivate the Nimble path -- --path/-p:PATH add path to search paths - - -configuration file hierarchy & precedence ------------------------------------------ -- file.nim passed to compile/run becomes the $project file name -- later files overwrite previous settings -- any OPT in this file can be specified in a cfg file; same format as cmd line args -- cmd line opts > cfg file opts - - install dirs: $nim/config/nim.cfg > etc/nim/nim.cfg [nix] | /config/nim.cfg [win] - - user dirs: $XDG_CONFIG_HOME/nim/nim.cfg | ~/.config/nim/nim.cfg [nix] | %APPDATA%/nim/nim.cfg [win] - - recursive parent dirs: $parentDir/nim.cfg all the way to root - - project dir: $projectDir/nim.cfg lives next to the $project file - - project cfg file: $projectDir/$project.nim.cfg +memory related define OPTS +-------------------------- +- --define:logGC gc logging to stdout +- --define:memProfiler memory profile for the native GC +- --define:useMalloc optimize for low memory systems using C's malloc instead of Nim's memory manager, requires --mm:none/arc/orc, also see nimPage256/516/1k & nimMemAlignTiny +- --define:useRealtimeGC support for soft realtime systems +- --mm:orc|arc|refc|markAndSweep|boehm|go|none|regions memory mgmt strategy, orc for new/async, arc|orc for realtime systems +- --sinkInference:on|off turn sink parameter inference on|off configuration OPTS ------------------ -- cli opts > file opts - - --skipCfg:on|off do not read the nim installation's configuration file - - --skipParentCfg:on|off do not read the parent dirs' configuration files - - --skipProjCfg:on|off do not read the project dir/file configuration file - - --skipUserCfg:on|off do not read the user's configuration +- --skipCfg:on|off do not read the nim installation's configuration file +- --skipParentCfg:on|off do not read the parent dirs' configuration files +- --skipProjCfg:on|off do not read the project dir/file configuration file +- --skipUserCfg:on|off do not read the user's configuration documention OPTS ---------------- @@ -187,25 +204,26 @@ documention OPTS debugging OPTS -------------- +- --defusages find the definition and usages of a symbol - --benchmarkVM:on|off with cpuTime() on|off - --profileVM:on|off VM profiler - --stdout:on|off output to stdout -- --debugger:native use native gdb debugger - --debuginfo:on|off debug information - --declaredLocs:on|off declaration locations in messages - --dump.format:json dump conditions & search paths as json -- --excessiveStackTrace:on|off stack traces use full file paths -- --run/-r run after compiling -- --showAllMismatches:on|off in overloading resolution - --stackTraceMsgs:on|off enable user defined stack frame msgs via setFrameMsg +- --processing:dots|filenames|off show files as their being compiled -runtime OPTS ------------- -- --putenv:key=value -- -d:nimMaxDescriptorsFallback=N for httpasyncserver +niche OPTS +---------- +- --colors:on|off for compiler msgs +- --exceptions:setjmp|cpp|goto|quirky exception handling implementation +- --trmacros:on|off term rewriting macros +- --index:on|off index file generation -specific runtime check OPTS ---------------------------- + +runtime check OPTS +------------------ - require :on/off, set all --checks/-x:on/off - --boundChecks - --fieldChecks @@ -216,36 +234,30 @@ specific runtime check OPTS - --overflowChecks - --rangeChecks -specific compiler hint OPTS ---------------------------- -- @see https://nim-lang.org/docs/nimc.html#compiler-usage-list-of-hints +compiler hint OPTS +------------------ +- @see https://nim-lang.github.io/Nim/nimc.html#compiler-usage-list-of-hints - can also be set via {.hint[woop]:on/off.} - require :on/off, set all --hints:on/off/list - --hint:woop: - --hintAsError:woop: - sometimes its just woop:off, instead of hint:woop:off -specific compiler warning OPTS ------------------------------- -- @see https://nim-lang.org/docs/nimc.html#compiler-usage-list-of-warnings +compiler warning OPTS +--------------------- +- @see https://nim-lang.github.io/Nim/nimc.html#compiler-usage-list-of-warnings - can also be set via {.warning[woop]:on/off.} - require :on/off, set all --warnings/-w:on|off|list +- @see https://nim-lang.github.io/Nim/nimc.html#compiler-usage-list-of-warnings - --warning:woop - --warningAsError:woop -compiler style check OPTS -------------------------- -- --styleCheck:off|hint|error hints or errors for identifiers conflicting with official style guide -- --styleCheck:usages enforce consistent spellings of identifiers, but not style declarations environment variables --------------------- - CC sets compiler when --cc:env is used - `-d:nimPreviewHashRef` enable hashing refs -type opts ---------- - skipped ------- - --app:lib something to do with generating dynamic libraries (grep os docs) @@ -253,7 +265,6 @@ skipped - --clib:LIBNAME - --clibdir:DIR - --cppCompileToNamespace:namespace -- --defusages - --dynlibOverride:SYMBOL - --dynlibOverrideAll - --eval:cmd @@ -265,9 +276,6 @@ skipped - --maxLoopIterationsVM:N - --passC/-t:OPTION e.g. option for the C compiler, e.g. optimization/cross compilation support - --passL/-l:OPTION e.g.option for the linker, e.g. cross compilation support -- --processing:dots|filenames|off -- --spellSuggest|:num -- --undefine/-u - --unitsep:on|off - --usenimcache - --useVersion:1.0|1.2 @@ -281,7 +289,7 @@ skipped - -d:nimStdSetjmp - -d:nimThreadStackGuard - -d:nimThreadStackSize -- -d:noSignalHandler @see https://nim-lang.org/docs/nimc.html#signal-handling-in-nim +- -d:noSignalHandler @see https://nim-lang.github.io/Nim/nimc.html#signal-handling-in-nim - -d:useFork - -d:useNimRtl - -d:useShPath @@ -297,6 +305,6 @@ skipped echo "############################ compile time checking" -# @see https://nim-lang.org/docs/system.html#compileOption%2Cstring%2Cstring +# @see https://nim-lang.github.io/Nim/system.html#compileOption%2Cstring%2Cstring when compileOption("opt", "size") and compileOption("gc", "boehm"): echo "compiled with optimization for size and uses Boehm's GC" diff --git a/src/bookofnim/deepdives/memoryRuntime.nim b/src/bookofnim/deepdives/memoryRuntime.nim index 9619a5e9..94cad53e 100644 --- a/src/bookofnim/deepdives/memoryRuntime.nim +++ b/src/bookofnim/deepdives/memoryRuntime.nim @@ -12,27 +12,37 @@ - are garbage collected - need to be initialized before used - are mutable, the ref always points to the same memory location +- value semantics + - sequences and strings are heap types BUT are copied on assignment like stack types - declaring variables as var - give value types heap semantics - if declared globally (module scoped) are stored in the executables data section (not the stack) +- ARC/ORC at runtime + - shallow/shallowoCopy arent defined for arc/orc + - use move /+ assignment and sink for optimization +- other MM + - shallow(blah) marks blah as shallow for optimization, subsequent assignments wont deep copy + - shallowCopy(x, y) copies y into x links ----- - [atomics](https://github.com/nim-lang/Nim/blob/devel/lib/pure/concurrency/atomics.nim) -- [lifetime-tracking hooks](https://nim-lang.org/docs/destructors.html#lifetimeminustracking-hooks) +- [destructors and move semantics](https://nim-lang.github.io/Nim/destructors.html) - [gc common](https://github.com/nim-lang/Nim/blob/devel/lib/system/gc_common.nim) -- [ref and pointer types](https://nim-lang.org/docs/manual.html#types-reference-and-pointer-types) +- [ref and pointer types](https://nim-lang.github.io/Nim/manual.html#types-reference-and-pointer-types) +- [mixing gced memory with ptr](https://nim-lang.github.io/Nim/manual.html#types-mixing-gc-ed-memory-with-nimptr) TODOs ----- - [] is the dereferencing sign - [see elegantbeefs response here](https://forum.nim-lang.org/t/10111) - reference all the ptr/ref/locks stuff in here -- add a test file -- hmm +- [addr docs](https://nim-lang.github.io/Nim/manual.html#statements-and-expressions-the-addr-operator) +- [ORC and threads discussion](https://forum.nim-lang.org/t/10155) +- [refc docs](https://nim-lang.github.io/Nim/refc.html) ## garbage collector safety - +- string, seq, ref and closures are always garbage collected - each thread - has an isolated memory heap; no sharing occurs - prevents race conditions and improves efficiency @@ -75,7 +85,6 @@ channels - useful when locks & guards are overkill ## types - stack (value) types ------------------- - array @@ -83,17 +92,35 @@ stack (value) types - int - object - set (system) +- char +- ptr/pointer types (alloc) heap (ref) types ---------------- - addr -- ptr/pointer untraced refs pointing to manually allocated objects, required for low-level ops +- ptr/pointer (malloc) untraced refs pointing to manually allocated objects, required for low-level ops - ref point to garbage-collected heap objects - seq - sets (hashSets) - sink - string -- unsafeAddr +- unsafeAddr deprecated + +copied on assignment +-------------------- +- sequences +- strings + +mutable +------- +- var +- ref/pointer types can always be mutated through a pointer + +immutable +--------- +- const (compile time) +- let (runtime, cant be reassigned) +- ref/pointer variables cant point to a new ref/pointer after procs ----- diff --git a/src/bookofnim/deepdives/osIo.nim b/src/bookofnim/deepdives/osIo.nim index af21fb99..e49a4407 100644 --- a/src/bookofnim/deepdives/osIo.nim +++ b/src/bookofnim/deepdives/osIo.nim @@ -1,7 +1,7 @@ ## ## os and i/o ## ========== -## [bookmark](https://nim-lang.org/docs/streams.html) +## [bookmark](https://nim-lang.github.io/Nim/streams.html) # ##[ @@ -67,43 +67,32 @@ links - other - [nitch source code](https://github.com/unxsh/nitch) - [peter: handling files in nim](https://peterme.net/handling-files-in-nim.html) + - [consuming data from thousands of small files](https://forum.nim-lang.org/t/10146) - high impact - - [basic os utils](https://nim-lang.org/docs/os.html) - - [distro detection & os pkg manager](https://nim-lang.org/docs/distros.html) + - [basic os utils](https://nim-lang.github.io/Nim/os.html) + - [distro detection & os pkg manager](https://nim-lang.github.io/Nim/distros.html) - [env support](https://nim-lang.github.io/Nim/envvars.html) - - [file and string streams](https://nim-lang.org/docs/streams.html) + - [file and string streams](https://nim-lang.github.io/Nim/streams.html) - [fusion file permissions](https://nim-lang.github.io/fusion/src/fusion/filepermissions.html) - [fusion io utils](https://nim-lang.github.io/fusion/src/fusion/ioutils.html) - [fusion scripting](https://nim-lang.github.io/fusion/src/fusion/scripting.html) - - [get cpu/cors info](https://nim-lang.org/docs/cpuinfo.html) - - [i/o multiplexing](https://nim-lang.org/docs/selectors.html) - - [mem files](https://nim-lang.org/docs/memfiles.html) - - [parse cmdline opts](https://nim-lang.org/docs/parseopt.html) - - [posix wrapper](https://nim-lang.org/docs/posix_utils.html) - - [process exec & comms](https://nim-lang.org/docs/osproc.html) - - [read stdin](https://nim-lang.org/docs/rdstdin.html) - - [system io](https://nim-lang.org/docs/io.html) - - [terminal](https://nim-lang.org/docs/terminal.html) + - [get cpu/cors info](https://nim-lang.github.io/Nim/cpuinfo.html) + - [i/o multiplexing](https://nim-lang.github.io/Nim/selectors.html) + - [mem files](https://nim-lang.github.io/Nim/memfiles.html) + - [parse cmdline opts](https://nim-lang.github.io/Nim/parseopt.html) + - [posix wrapper](https://nim-lang.github.io/Nim/posix_utils.html) + - [process exec & comms](https://nim-lang.github.io/Nim/osproc.html) + - [read stdin](https://nim-lang.github.io/Nim/rdstdin.html) + - [system io](https://nim-lang.github.io/Nim/io.html) + - [terminal](https://nim-lang.github.io/Nim/terminal.html) - [temp files and directories](https://github.com/nim-lang/Nim/blob/devel/lib/std/tempfiles.nim) - niche - - [open users browser](https://nim-lang.org/docs/browsers.html) - - [raw posix interface]https://nim-lang.org/docs/posix.html + - [open users browser](https://nim-lang.github.io/Nim/browsers.html) + - [raw posix interface]https://nim-lang.github.io/Nim/posix.html TODOs ----- -- cpuEndian -- cpuRelax -- DynlibFormat, ExeExt[s], ScriptExt -- [find instantiationInfo in the docs](https://stackoverflow.com/questions/55891650/how-to-use-slurp-gorge-staticread-staticexec-in-the-directory-of-the-callsite) - - -## system - -vars/procs/etc --------------- -- hostCPU - - "i386", "alpha", "powerpc", "powerpc64", - - "powerpc64el", "sparc", "amd64", "mips", +- cpuEndianwarning"mips", - "mipsel", "arm", "arm64", "mips64", "mips64el", "riscv32", "riscv64" - hostOS - "windows", "macosx", "linux", "netbsd", @@ -115,7 +104,7 @@ vars/procs/etc - fmReadWriteExisting same but doesnt create file - fmAppend append doesnt create file - getFreeMem number of bytes owned by the process, but do not hold any meaningful data - +- file and open arent in system anymore ## os @@ -271,6 +260,8 @@ parseopt iterators ]## +{.push hint[XDeclaredButNotUsed]: off.} + import std/[sugar, strformat, strutils, sequtils, tables] echo "############################ system" @@ -404,10 +395,10 @@ echo fmt"{addFileExt someFile, md=}" echo fmt"{addFileExt someFile & $'.' & md, txt=}" echo fmt"{changeFileExt someFile.addFileExt md, txt=}" echo fmt"{expandFilename somefile.addFileExt md=}" -echo fmt"{getCreationTime readme=}" -echo fmt"{getLastAccessTime readme=}" -echo fmt"{getLastModificationTime readme=}" -echo fmt"bunch of stuff {getFileInfo readme=}" +# echo fmt"{getCreationTime readme=}" # TODO(noah): throws in v2 +# echo fmt"{getLastAccessTime readme=}" # TODO(noah): throws in v2 +# echo fmt"{getLastModificationTime readme=}" # TODO(noah): throws in v2 +# echo fmt"bunch of stuff {getFileInfo readme=}" # TODO(noah): throws in v2 echo fmt"bytes {getFileSize readme=}" echo fmt"{isValidFilename absolutePath readme=}" echo fmt"{sameFile readme, readme=}" @@ -417,59 +408,63 @@ echo fmt"{readme.absolutePath.splitFile=}" const helloworldReadme = "src/bookofnim/helloworld/helloworld.md" -let entireFile = try: readFile helloworldReadme except: "" ## \ - ## calls readAll then closes the file afterwards - ## raises IO exception on err - ## use staticRead instead for compiletime -if entireFile.len is Positive: - echo "file has ", len entireFile, " characters" - - -let first5Lines = try: readLines helloworldReadme, 5 except: @[] ## \ - ## raises IO exception on err, EOF if N > lines in file - ## lines must be delimited by LF/CRLF - ## available at compiletime -for line in first5Lines: echo "say my line: ", line - -proc readFile: string = - let f = open helloworldReadme ## \ - ## open string, fMode = fmRead, bufSize = -1: File - ## open File; string/filehandle; fmode = fmRead: bool - ## can pass bufSize whenever you pass a string - defer: close f ## \ - ## make sure to close the file object - echo "i started to read when I was ", getFilePos f - echo "first line in file is: ", readLine f - echo if endOfFile f: "game over" else: "hooked on phonics worked for me" - echo "we need to get a handle on this file ", getFileHandle f ## \ - ## returns the C library's handle on the file - echo "so instead use ", getOsFileHandle f ## \ - ## useful for platform specific logic - ## perhaps always use getOsFileHandle, dunno - echo "but wasnt good until i turned ", getFilePos f - echo "reading so much I gained ", getFileSize f, " in bytes" - result = readLine f -echo "the current line in file is ", readFile() - -try: - for line in helloworldReadme.lines: echo "loop over line: ", line ## \ - ## append .lines to the string/File - ## else it loops over the filename (not the content) - ## raises IOError if file doesnt exist -except: echo "maybe file doesnt exist?" +# TODO(noah): readFile isnt system in v2? +# let entireFile = try: readFile helloworldReadme except: "" ## \ +# ## calls readAll then closes the file afterwards +# ## raises IO exception on err +# ## use staticRead instead for compiletime +# if entireFile.len is Positive: +# echo "file has ", len entireFile, " characters" + +# TODO(noah): readLines isnt system in v2? +# let first5Lines = try: readLines helloworldReadme, 5 except: @[] ## \ +# ## raises IO exception on err, EOF if N > lines in file +# ## lines must be delimited by LF/CRLF +# ## available at compiletime +# for line in first5Lines: echo "say my line: ", line + +# TODO(noah): readFile isnt system in v2 +# proc readFile: string = +# let f = open helloworldReadme ## \ +# ## open string, fMode = fmRead, bufSize = -1: File +# ## open File; string/filehandle; fmode = fmRead: bool +# ## can pass bufSize whenever you pass a string +# defer: close f ## \ +# ## make sure to close the file object +# echo "i started to read when I was ", getFilePos f +# echo "first line in file is: ", readLine f +# echo if endOfFile f: "game over" else: "hooked on phonics worked for me" +# echo "we need to get a handle on this file ", getFileHandle f ## \ +# ## returns the C library's handle on the file +# echo "so instead use ", getOsFileHandle f ## \ +# ## useful for platform specific logic +# ## perhaps always use getOsFileHandle, dunno +# echo "but wasnt good until i turned ", getFilePos f +# echo "reading so much I gained ", getFileSize f, " in bytes" +# result = readLine f +# echo "the current line in file is ", readFile() + +# TODO(noah): lines isnt system in v2 +# try: +# for line in helloworldReadme.lines: echo "loop over line: ", line ## \ +# ## append .lines to the string/File +# ## else it loops over the filename (not the content) +# ## raises IOError if file doesnt exist +# except: echo "maybe file doesnt exist?" # upsert a file const tmpfile = "/tmp/helloworld.txt" -writeFile tmpfile, "a luv letter to nim" -echo readFile tmpfile +# writeFile tmpfile, "a luv letter to nim" # TODO(noah): writeFile isnt system in v2 +# echo readFile tmpfile # overwrite an existing file -proc writeLines(s: seq[string]): void = - let f = tmpfile.open(fmWrite) # open for writing - defer: close f - for i, l in s: f.writeLine l -writeLines @["first line", "Second line"] -echo readFile tmpfile +# TODO(noah): open isnt system in v2 +# proc writeLines(s: seq[string]): void = +# let f = tmpfile.open(fmWrite) # open for writing +# defer: close f +# for i, l in s: f.writeLine l +# writeLines @["first line", "Second line"] +# echo readFile tmpfile echo "############################ os permissions/user" # copyFileWithPermissions src, dest, ignorePermErrs = true, options @@ -514,7 +509,7 @@ echo "############################ os/system exec/cmds/process" when defined(linux): echo fmt"{osErrorMsg OSErrorCode 0=}" echo fmt"{osErrorMsg OSErrorCode 1=}" - echo fmt"{osErrorMsg OSErrorCode osLastError()=}" + echo fmt"{osErrorMsg osLastError()=}" if fmt"tree -L 1 {tmpdir.parentDir} | grep -E [n,m]i[n,m]".execShellCmd != 0: ## \ @@ -533,10 +528,11 @@ echo fmt"""{findExe "nim"=}""" # echo "whats your name: " # echo "hello: ", readLine(stdin) disabled cuz it stops code runner -stdout.writeLine "equivalent to an echo" -flushFile stdout -stderr.writeLine "but i only see red" -flushFile stderr +# TODO(noah): stdout/err arent system in v2 +# stdout.writeLine "equivalent to an echo" +# flushFile stdout +# stderr.writeLine "but i only see red" +# flushFile stderr # docs const buildInfo = "Revision " & staticExec("git rev-parse HEAD") & @@ -611,17 +607,18 @@ var proc printToken(kind: CmdLineKind, key: string, val: string) = ## copied from docs case kind - of cmdEnd: doAssert(false) # Doesn't happen with getopt() + # of cmdEnd: doAssert(false) # TODO(noah): doAssert isnt system in v2 of cmdShortOption, cmdLongOption: echo fmt"long/short option {key=} {val=}" of cmdArgument: echo fmt"cmd arg {key=} " + else: discard # TODO(noah): hack for doAssert not being system -echo "\n\n", fmt"{cmdxOpts=}" +# echo "\n\n", fmt"{cmdxOpts=}" # TODO(noah): throws in v2 for kind, key, val in cmdxOpts.getopt(): printToken(kind, key, val) -echo "\n\n", fmt"{cmdyOpts=}" +# echo "\n\n", fmt"{cmdyOpts=}" # TODO(noah): throws in v2 for kind, key, val in cmdyOpts.getopt(): printToken(kind, key, val) -echo "\n\n", fmt"{cmdzOpts=}" +# echo "\n\n", fmt"{cmdzOpts=}" # TODO(noah): throws in v2 for kind, key, val in cmdzOpts.getopt(): printToken(kind, key, val) var p = initOptParser(myOptsArgDash) diff --git a/src/bookofnim/deepdives/packaging.nim b/src/bookofnim/deepdives/packaging.nim index a09ae432..4e7fd921 100644 --- a/src/bookofnim/deepdives/packaging.nim +++ b/src/bookofnim/deepdives/packaging.nim @@ -20,13 +20,13 @@ links - [configs used by nim](https://github.com/nim-lang/Nim/tree/devel/config) - [example config with tasks](https://github.com/kaushalmodi/nim_config/blob/master/config.nims) - [nimble repo](https://github.com/nim-lang/nimble) - - [understanding how nim is built for X may help you do the same](https://nim-lang.org/docs/packaging.html) + - [understanding how nim is built for X may help you do the same](https://nim-lang.github.io/Nim/packaging.html) - high impact docs - [nimble pkg reference](https://github.com/nim-lang/nimble#nimble-reference) - - [nims intro](https://nim-lang.org/docs/nims.html) - - [parse config](https://nim-lang.org/docs/parsecfg.html) + - [nims intro](https://nim-lang.github.io/Nim/nims.html) + - [parse config](https://nim-lang.github.io/Nim/parsecfg.html) - niche - - [base object of a lexer](https://nim-lang.org/docs/lexbase.html) + - [base object of a lexer](https://nim-lang.github.io/Nim/lexbase.html) - source - abc diff --git a/src/bookofnim/deepdives/pragmasEffects.nim b/src/bookofnim/deepdives/pragmasEffects.nim index 0305608a..e50ac27f 100644 --- a/src/bookofnim/deepdives/pragmasEffects.nim +++ b/src/bookofnim/deepdives/pragmasEffects.nim @@ -1,36 +1,51 @@ ## ## pragmas, effects and experimental features ## ========================================== -## - [bookmark](https://nim-lang.org/docs/manual.html#effect-system-tag-tracking) +## - [bookmark](https://nim-lang.github.io/Nim/manual.html#effect-system-tag-tracking) ##[ ## TLDR - pragmas - - syntax: `{.pragma1, pragma2:val, etc.}` + - syntax: `{.pragma1, pragma2:val, type[pragma]:val, etc.}` - many pragmas require familiarity of C/C++/objc - - FYI: - - a futile attempt was taken at categorizing pragmas - - template annotation & macro pragmas are in templateMacros.nim - - thread/async pragmas are in asyncPar.nim + - FYI: a futile attempt was taken at categorizing pragmas - effect system consists of - - proc exception tracking - - user defined effect tag tracking - - functional side effect tracking + - and empty [] in raises/tags declares none are permitted + - compile time routine CatchableError tracking {.raises: [commaSeparated] .} + - compile time tracking of exception types a routine can/t throw + - user defined effect tag (type) tracking {.tags:[commaSeparated}.} + - create a type that denotes some user defined thing you want to track + - apply tag(s) to routine A to permit + - apply empty [] or {.forbids: [commaSeparated] .} to routine B to restrict calls to routine A + - functional side effect tracking (implies gc safety below) + - {.noSideEffect.} throws if this routine has sideEffects + - {.cast(noSideEffect).}: disables side effect tracking + - a routine has no sideEffects if: + - it doesnt access a threadlocal/global var + - does not invoke a routine that does - memory/gc safety tracking + - a routine is GC safe if: + - doesnt (in)directly access global vars of type string, seq, ref or closures + - {.gcsafe.} throws if a routine is unsafe + - {.cast(gcsafe).} disables safety tracking + - effect logging + - a single line with {.effects.} causes the compiler to output all effects up to that point links ----- - other - [wikipedia side effects](https://en.wikipedia.org/wiki/Effect_system) -- [pragmas section in manual](https://nim-lang.org/docs/manual.html#pragmas) -- [effect system in manual](https://nim-lang.org/docs/manual.html#effect-system) +- [effect system intro](https://nim-lang.github.io/Nim/manual.html#effect-system) +- [list of effects](https://github.com/nim-lang/Nim/blob/devel/lib/system/exceptions.nim) +- [pragmas intro](https://nim-lang.github.io/Nim/manual.html#pragmas) TODOs ----- -- [effect system](https://nim-lang.org/docs/manual.html#effect-system) -- [experimental](https://nim-lang.org/docs/manual_experimental.html) +- [experimental features](https://nim-lang.github.io/Nim/manual_experimental.html) +- [dot operator template](https://nim-lang.github.io/Nim/manual_experimental.html#special-operators-dot-operators) - move all the C pragmas into the backends dir - [document the effect types from devel branch](https://github.com/nim-lang/Nim/blob/devel/lib/system/exceptions.nim) +- distribute the pragmas in this file into other files, but keep this comprehensive list up to date ## pragmas - enable new functionality without adding new keywords to the language @@ -59,11 +74,10 @@ custom pragmas - booldefine same as intdefine but for bools - user defined pragmas: WOOP is a new pragma, - pragma:WOOP, pragmaX, pragmaY -- see templateMacros.nim for template pragmas universal pragmas ----------------- -- compileTime marks proc as compile time only; vars init during compile and const at runtime +- compileTime marks symbol as compile time only; vars init during compile and const at runtime - deprecated: "optional msg" flag, prints warning in compiler logs if symbol is used - effects will output all inferred effects (e.g. exceptions) up to this point - error: "msg" annotate a symbol with an error msg; when the symbol is used a static error is thrown @@ -73,11 +87,17 @@ universal pragmas - push: x,y,z add pragmas until popped, e.g. {.push hints:off, warning[blah]: on.} - used: inform the compiler this symbol/module is used, and not to print warning about it - warning: "msg" same as error but for warnings +- hint: "msg" output a a hint when symbol is used var pragmas ----------- -- global converts a proc scoped var into a global -- threadvar informs the compiler this var should be local to a thread +- global stores a proc scoped var in a global location so its initialized only once at startup +- register this variable for placement in a hardware register for faster access + +thread pragmas +-------------- +- thread this proc can be passed to createThread/spawn +- threadvar this var is local to a thread, implies global pragma routine pragmas --------------- @@ -85,11 +105,11 @@ routine pragmas - base method used on a base type for inheritable objects - closure - effectsOf: paramX inform the compiler this proc has the effects of paramX +- inline this proc at the callsite instead of calling it - noReturn proc that never returns - noSideEffect proc is interpreted as a func (see routines.nim) - raises: [x,y,z] list permitted exceptions; non listed force compiler errs - tags: [x,y,z] list of user defined effects to enforce -- thread informs the compiler this proc is meant for execution on a new thread - varags this proc can take a variable number of params after the last one type pragmas @@ -101,18 +121,39 @@ type pragmas - inheritable create alternative RootObj - overloadableEnums allows two Enums to have same fieldnames, to be resolved at runtime - packed sets an objects field back to back in memory; e.g. for network/hardware drivers -- pure requires enums to be fully qualified; x fails, but y.x doesnt -- shallow objects can be shallow copied; use w/ caution; speeds up assignments considerably +- pure requires enums to be fully qualified; or omit an objects type field at runtime +- shallow copy on assignment; breaks GC safety; speeds up assignments considerably - union sets an objects fields overlaid in memory producing a union instead of struct in C/++ +- forbids from invoking/consuming type T +- noinit do not initialize this symbol with a default value (optimization) +- requiresInit throw error if this symbol is later used without first being initialized JS pragmas ---------- - importJs fns/symbols that can be called via `obj.fn(args)` -experimental pragmas --------------------- -- enable experimental features - - parallel +experimental: "woop" +------------------------ +- FYI: + - can be applied to a symbol / module / config switch +- callOperator enabless overload `(a[,b...])` so it calls a template like `blah(a,...)` +- dotOperators enable overloading `a.b | a.b = c` so it calls a template like `blah(a,b,c)` +- flexibleOptionalParams allows optional parameters in combination with `: body` +- notnil enables annotating nillable types to be initialized with non nill values at compile time +- parallel mechanism for safer parallel logic via compiler checks during semantic analysis +- strictCaseObjects requires every field access to be valid at compile time +- strictDefs every local variable must be initialized explicitly before use (except with let) +- strictFuncs implements a stricter definition of `side effect` when impacts ref/ptr types +- strictNotNil also checks builtin and imported modules +- views a variable that is/contains a non ptr/proc lent/openArray; best used with strictFuncs + +template pragmas +---------------- +- redefine a template symbols as long as the signature doesnt change + +macro pragmas +------------- +- command compilation pragmas ------------------- @@ -120,14 +161,12 @@ compilation pragmas - boundChecks:on/off - callconv:on/off - checks:on/off -- hint[woop]:on/off -- hints:on/off +- hints:on/off or hint[woop]:on/off - nilChecks:on/off - optimization:none/speed/size - overflowChecks: on/off - patterns:on/off -- warning[woop]:on/off -- warnings:on/off +- warnings:on/off or warning[woop]:on/off niche pragmas ------------- @@ -137,33 +176,34 @@ niche pragmas unknown/skipped/C pragmas ------------------------- -- align +- align for variables and object field members - bitsize - codegenDecl - compile - computedGoTo dunno; something to do with case statements in a while loop and interpreters - cpopNonPod +- cppNonPod - dirty something to do with templates - discardable -- dynlib: "exactName" import a proc/var from a dynamic .{dll,so} library - dynlib export this symbol to a dynamic library, must be used with exportc +- dynlib: "exactName" import a proc/var from a dynamic .{dll,so} library - emit - exportc: "optionalName" use the symbols/provided name when exporting this to c - extern: "x$1" affects symbol name mangling when exported -- header +- header dont declare this symbol in C, instead create an include statement - importc import a proc/var from C - importCpp - importObjC - incompleteStruct - inject something to do with symbol visibility -- inline a proc; dunno what that means - link - localPassc -- nodecl +- noalias mapped to Cs restrict keyword +- nodecl dont generate a declaration for the symbol in C, use header pragma instead - passc - passl -- registerProc dunno; included in the compileTime example -- size dunno +- registerProc included in the compileTime example +- size - volatile @@ -216,7 +256,7 @@ effect types echo "############################ push/pop pragma" -# @see https://nim-lang.org/docs/manual.html#pragmas-push-and-pop-pragmas +# @see https://nim-lang.github.io/Nim/manual.html#pragmas-push-and-pop-pragmas # this (im-status) trick prohibits procs from throwing defects, but allows errors # compiler will throw if its analysis determines a proc can throw a defect, helps u debug diff --git a/src/bookofnim/deepdives/servers.nim b/src/bookofnim/deepdives/servers.nim index 4f21ec88..963d40b6 100644 --- a/src/bookofnim/deepdives/servers.nim +++ b/src/bookofnim/deepdives/servers.nim @@ -1,7 +1,7 @@ ## ## servers ## ======= -## [bookmark](https://nim-lang.org/docs/asynchttpserver.html#acceptRequest%2CAsyncHttpServer%2Cproc%28Request%29) +## [bookmark](https://nim-lang.github.io/Nim/asynchttpserver.html#acceptRequest%2CAsyncHttpServer%2Cproc%28Request%29) ##[ ## TLDR @@ -45,17 +45,17 @@ links ----- - high impact - - [cookies](https://nim-lang.org/docs/cookies.html) - - [ftp client (async)](https://nim-lang.org/docs/asyncftpclient.html) - - [http a/sync client](https://nim-lang.org/docs/httpclient.html) - - [http server (async)](https://nim-lang.org/docs/asynchttpserver.html) - - [socket server (async)](https://nim-lang.org/docs/asyncnet.html) - - [socket server](https://nim-lang.org/docs/net.html) - - [uri interface](https://nim-lang.org/docs/uri.html) + - [cookies](https://nim-lang.github.io/Nim/cookies.html) + - [ftp client (async)](https://nim-lang.github.io/Nim/asyncftpclient.html) + - [http a/sync client](https://nim-lang.github.io/Nim/httpclient.html) + - [http server (async)](https://nim-lang.github.io/Nim/asynchttpserver.html) + - [socket server (async)](https://nim-lang.github.io/Nim/asyncnet.html) + - [socket server](https://nim-lang.github.io/Nim/net.html) + - [uri interface](https://nim-lang.github.io/Nim/uri.html) - niche - - [email cilent](https://nim-lang.org/docs/smtp.html) - - [shared a/sync http primitives](https://nim-lang.org/docs/httpcore.html) - - [low level native socket interface](https://nim-lang.org/docs/nativesockets.html) + - [email cilent](https://nim-lang.github.io/Nim/smtp.html) + - [shared a/sync http primitives](https://nim-lang.github.io/Nim/httpcore.html) + - [low level native socket interface](https://nim-lang.github.io/Nim/nativesockets.html) TODOs @@ -127,7 +127,7 @@ httpclient procs - body of a response - close connects held by an http client - code corronspding to a response status -- contentLength from response header, throws if not an int +- contentLength from response header, defaults to -1 - contentType from response header - getSocket for details about current connection - lastModified from response header @@ -166,6 +166,7 @@ asynchttpserver procs - acceptRequest ]## +{.push hint[XDeclaredButNotUsed]:off .} import std/[strformat, strutils, json] @@ -188,45 +189,45 @@ echo "############################ httpclient sync" let fetch = newHttpClient(timeout = timeout) -echo fmt"{fetch.getContent getmegood=}" -echo fmt"{fetch.get(getmegood).body=}" -echo fmt"{fetch.get(getmegood).headers=}" -echo fmt"{fetch.get(getmegood).version=}" -echo fmt"{fetch.get(getmegood).status=}" -echo fmt"{fetch.get(getmebad).status=}" +# echo fmt"{fetch.getContent getmegood=}" # TODO(noah): v2 / config.nims: Uninit +# echo fmt"{fetch.get(getmegood).body=}" +# echo fmt"{fetch.get(getmegood).headers=}" +# echo fmt"{fetch.get(getmegood).version=}" +# echo fmt"{fetch.get(getmegood).status=}" +# echo fmt"{fetch.get(getmebad).status=}" fetch.headers = newHttpHeaders({ "Content-Type": "application/json" }) echo fmt"{fetch.postContent postme, body = $data=}" -fetch.headers = newHttpHeaders({ "X-Vault-Token": "abc-123-321-cba" }) -try: echo fmt"{fetch.getContent getmetimeout=}" except CatchableError: echo "gotta catchem all!" +# fetch.headers = newHttpHeaders({ "X-Vault-Token": "abc-123-321-cba" }) +# try: echo fmt"{fetch.getContent getmetimeout=}" except CatchableError: echo "gotta catchem all!" -fetch.close +# fetch.close echo "############################ httpclient async" -import std/[asyncdispatch, options] # httpclient already imported above +# import std/[asyncdispatch, options] # httpclient already imported above -let afetch = newAsyncHttpClient() +# let afetch = newAsyncHttpClient() -proc agetContent(self: AsyncHttpClient, url: string): Future[Option[string]] {.async.} = - ## wraps async calls to provide await for AsyncHttpClient - let res = self.getContent url - yield res; - result = if res.failed: none string else: some res.read +# proc agetContent(self: AsyncHttpClient, url: string): Future[Option[string]] {.async.} = +# ## wraps async calls to provide await for AsyncHttpClient +# let res = self.getContent url +# yield res; +# result = if res.failed: none string else: some res.read -echo fmt"{waitFor afetch.agetContent getmegood=}" +# echo fmt"{waitFor afetch.agetContent getmegood=}" # FYI: this cause asyncnet to throw on v2 # echo fmt"{waitFor withTimeout(afetch.agetContent(getmegood), 1)=}" # you should instead yield all async requests -proc fetchWithTimeout: Future[void] {.async.} = - let aResponse = withTimeout(afetch.agetContent(getmegood), 1) - yield aResponse - echo if aResponse.failed: "failed with error" else: fmt"request success: {aResponse.read=}" -waitFor fetchWithTimeout() +# proc fetchWithTimeout: Future[void] {.async.} = +# let aResponse = withTimeout(afetch.agetContent(getmegood), 1) +# yield aResponse +# echo if aResponse.failed: "failed with error" else: fmt"request success: {aResponse.read=}" +# waitFor fetchWithTimeout() -afetch.close +# afetch.close diff --git a/src/bookofnim/deepdives/strings.nim b/src/bookofnim/deepdives/strings.nim index 92fc4425..cbf59478 100644 --- a/src/bookofnim/deepdives/strings.nim +++ b/src/bookofnim/deepdives/strings.nim @@ -1,7 +1,7 @@ ## ## strings ## ======= -## [bookmark](https://nim-lang.org/docs/uri.html) +## [bookmark](https://nim-lang.github.io/Nim/uri.html) ##[ ## TLDR @@ -12,20 +12,20 @@ links ----- - high impact - - [str format](https://nim-lang.org/docs/strformat.html) - - [str utils](https://nim-lang.org/docs/strutils.html) - - [uri parsing](https://nim-lang.org/docs/uri.html) + - [str format](https://nim-lang.github.io/Nim/strformat.html) + - [str utils](https://nim-lang.github.io/Nim/strutils.html) + - [uri parsing](https://nim-lang.github.io/Nim/uri.html) - niche - - [cstr utils](https://nim-lang.org/docs/cstrutils.html) - - [ropes (very long strings)](https://nim-lang.org/docs/ropes.html) - - [str (high perf) utils](https://nim-lang.org/docs/strbasics.html) - - [str misc](https://nim-lang.org/docs/strmisc.html) - - [unicode](https://nim-lang.org/docs/unicode.html) - - [unicode decode](https://nim-lang.org/docs/unidecode.html) - - [word wrap](https://nim-lang.org/docs/wordwrap.html) - - [encodings](https://nim-lang.org/docs/encodings.html) - - [edit distance](https://nim-lang.org/docs/editdistance.html) - - [punycode](https://nim-lang.org/docs/punycode.html) + - [cstr utils](https://nim-lang.github.io/Nim/cstrutils.html) + - [ropes (very long strings)](https://nim-lang.github.io/Nim/ropes.html) + - [str (high perf) utils](https://nim-lang.github.io/Nim/strbasics.html) + - [str misc](https://nim-lang.github.io/Nim/strmisc.html) + - [unicode](https://nim-lang.github.io/Nim/unicode.html) + - [unicode decode](https://nim-lang.github.io/Nim/unidecode.html) + - [word wrap](https://nim-lang.github.io/Nim/wordwrap.html) + - [encodings](https://nim-lang.github.io/Nim/encodings.html) + - [edit distance](https://nim-lang.github.io/Nim/editdistance.html) + - [punycode](https://nim-lang.github.io/Nim/punycode.html) TODOs @@ -48,17 +48,17 @@ TODOs ## strformat - simply importing strformat enhances the system & operator - doesnt interprate literal escapes like & does e.g. fmt"{str1}\n\n\n" -- escape works with these [char](https://nim-lang.org/docs/manual.html#lexical-analysis-character-literals) and [string](https://nim-lang.org/docs/manual.html#lexical-analysis-string-literals) literals +- escape works with these [char](https://nim-lang.github.io/Nim/manual.html#lexical-analysis-character-literals) and [string](https://nim-lang.github.io/Nim/manual.html#lexical-analysis-string-literals) literals - for others use a hex/decimal char/string - if an API returns a string regex containing `\s` im sure theres something in regex.nim that can help - fmt syntax: [[fill]align][sign][#][0][minimumwidth][.precision][type] - 3 align flags: > < ^ - 3 sign flags for numbers: + - (space) - additional flags exist specifically for integers & floats -- [fmt floats section is interesting](https://nim-lang.org/docs/strformat.html#formatting-floats) - - [as is fmt expressions](https://nim-lang.org/docs/strformat.html#expressions) - - [shiz gets crazy](https://nim-lang.org/docs/strformat.html#implementation-details) - - [flags for fmt](https://nim-lang.org/docs/strformat.html#standard-format-specifiers-for-strings-integers-and-floats) +- [fmt floats section is interesting](https://nim-lang.github.io/Nim/strformat.html#formatting-floats) + - [as is fmt expressions](https://nim-lang.github.io/Nim/strformat.html#expressions) + - [shiz gets crazy](https://nim-lang.github.io/Nim/strformat.html#implementation-details) + - [flags for fmt](https://nim-lang.github.io/Nim/strformat.html#standard-format-specifiers-for-strings-integers-and-floats) ## strutils - AllChars (and related) useful for creating inverted sets to check for invalid chars in a string @@ -66,7 +66,7 @@ TODOs - stripLineEnd is useful conjunction with osproc.execCmdEx - skipped type conversion procs; check skipped for the ones we skipped - the split like procs also have an iterator syntax that accepts a block -- [tokenize looks interesting](https://nim-lang.org/docs/strutils.html#tokenize.i%2Cstring%2Cset%5Bchar%5D) +- [tokenize looks interesting](https://nim-lang.github.io/Nim/strutils.html#tokenize.i%2Cstring%2Cset%5Bchar%5D) ## string formatters - strutils: "$1 $2" % ["first, "second"] diff --git a/src/bookofnim/deepdives/sugar.nim b/src/bookofnim/deepdives/sugar.nim index 8b0ebf08..ef59b927 100644 --- a/src/bookofnim/deepdives/sugar.nim +++ b/src/bookofnim/deepdives/sugar.nim @@ -8,16 +8,20 @@ - the sweetest nim syntax - the fusion pkg provides additional sugar, but its modules are dispersed through other files - working with data structures (e.g. sorting) generally requires std/algorithm +- do + - do with paranthesis creates an anonymous proc closure + - do without paranthesis is just a block of code links ----- - high impact - - [sugar](https://nim-lang.org/docs/sugar.html) - - [with](https://nim-lang.org/docs/with.html) - - [algorithm](https://nim-lang.org/docs/algorithm.html) - - [enumarate any collection](https://nim-lang.org/docs/enumerate.html) + - [sugar](https://nim-lang.github.io/Nim/sugar.html) + - [with](https://nim-lang.github.io/Nim/with.html) + - [algorithm](https://nim-lang.github.io/Nim/algorithm.html) + - [enumarate any collection](https://nim-lang.github.io/Nim/enumerate.html) - [wrapnils optional chaining](https://nim-lang.github.io/Nim/wrapnils.html) - - [system do notation](https://nim-lang.org/docs/manual_experimental.html#do-notation) + - [do notation](https://nim-lang.github.io/Nim/manual.html#procedures-do-notation) + - niche - [import private symbols](https://github.com/nim-lang/Nim/blob/devel/lib/std/importutils.nim) @@ -33,13 +37,12 @@ TODOs - std/algorithm - then review all the sort procs for each datatype (they all depend on algo) -## do blocks and proc fn signatures +## do statements, blocks and last proc params +- can be used when the last param of a proc invocation expects a routing + - i.e. `foo(a, b, proc () = ...)` == `foo(a, b) do (): ...` or - do blocks can be considered an alias for `block:` -- proc expressions can use do notation when passed as a parameter to a proc -- can also be used to pass multiple blocks to a macro -- i.e. - - do with paranthesis is an anonymous proc - - do without paranthesis is just a block of code + - can also be used to pass multiple blocks to a macro + - allows macros to receive both indented statements lists ## sugar diff --git a/src/bookofnim/deepdives/targeting.nim b/src/bookofnim/deepdives/targeting.nim index 9a5a74a3..c7c6ddce 100644 --- a/src/bookofnim/deepdives/targeting.nim +++ b/src/bookofnim/deepdives/targeting.nim @@ -6,7 +6,7 @@ ## TLDR - come back later - provide details on using the 4 backends to target specific runtime environments -- the 4 backends enable you to target [pretty much anything](https://nim-lang.org/docs/distros.html#7) +- the 4 backends enable you to target [pretty much anything](https://nim-lang.github.io/Nim/distros.html#7) links ----- @@ -14,7 +14,7 @@ links - [wrapping c libraries](https://peterme.net/wrapping-c-libraries-in-nim.html) - high impact - [default platforms](https://github.com/nim-lang/Nim/blob/devel/lib/system/platforms.nim) - - [cross compiling](https://nim-lang.org/docs/nimc.html#crossminuscompilation) + - [cross compiling](https://nim-lang.github.io/Nim/nimc.html#crossminuscompilation) TODOs ----- diff --git a/src/bookofnim/deepdives/templateMacros.nim b/src/bookofnim/deepdives/templateMacros.nim index ba4447f6..66c6e0ca 100644 --- a/src/bookofnim/deepdives/templateMacros.nim +++ b/src/bookofnim/deepdives/templateMacros.nim @@ -1,38 +1,46 @@ ## templates and macros ## ==================== -## [bookmark](https://nim-lang.org/docs/manual.html#templates) +## [bookmark](https://nim-lang.github.io/Nim/manual.html#templates) ##[ ## TLDR - pretty much skipped the entire section on templates, and definitely on macros - FYI: you dont know nim if you dont know templates & macros +links +----- +- [templates](https://nim-lang.github.io/Nim/manual.html#templates) +- [macros](https://nim-lang.github.io/Nim/manual.html#macros) + TODOs ----- +- [dynamic arguments for bindSym](https://nim-lang.github.io/Nim/manual_experimental.html#dynamic-arguments-for-bindsym) +- [term rewriting macros](https://nim-lang.github.io/Nim/manual_experimental.html#term-rewriting-macros) - niminaction: chapter 9 -- [macros](https://nim-lang.org/docs/manual.html#macros) +- [macros](https://nim-lang.github.io/Nim/manual.html#macros) - ^ continue until you get to SpecialTypes -- [macro tut](https://nim-lang.org/docs/tut3.html) +- [macro tut](https://nim-lang.github.io/Nim/tut3.html) - [fusion astdsl](https://nim-lang.github.io/fusion/src/fusion/astdsl.html) - [templates vs generics](https://forum.nim-lang.org/t/9985) -- [system.nimNode is discussed here](https://nim-lang.org/docs/manual.html#pragmas-compiletime-pragma) -- [typed vs untyped for templates](https://nim-lang.org/docs/manual.html#templates-typed-vs-untyped-parameters) -- [custom annotations with template pragmas](https://nim-lang.org/docs/manual.html#userminusdefined-pragmas-custom-annotations) -- [macro pragmas](https://nim-lang.org/docs/manual.html#userminusdefined-pragmas-macro-pragmas) +- [system.nimNode is discussed here](https://nim-lang.github.io/Nim/manual.html#pragmas-compiletime-pragma) +- [entire templates section](https://nim-lang.github.io/Nim/manual.html#templates-typed-vs-untyped-parameters) +- [custom annotations with template pragmas](https://nim-lang.github.io/Nim/manual.html#userminusdefined-pragmas-custom-annotations) +- [macro pragmas](https://nim-lang.github.io/Nim/manual.html#userminusdefined-pragmas-macro-pragmas) - [asyncmacro](https://github.com/nim-lang/Nim/blob/devel/lib/pure/asyncmacro.nim) - put the asyncdispatch templates in this file -- niminaction chapter 9 + + ## templates - simple form of a macro -- [supports lazy evaluation](https://nim-lang.org/docs/manual.html#overload-resolution-lazy-type-resolution-for-untyped) +- [supports lazy evaluation](https://nim-lang.github.io/Nim/manual.html#overload-resolution-lazy-type-resolution-for-untyped) - enables raw code substitution on nim's abstract syntax tree - are processed in the semantic pass of the compiler - accepts meta types template types -------------- -- untyped an expression thats not resolved for lazy evaluation +- untyped an expression thats not resolved, i.e. lazy evaluation that prevents type checking - typed an expression that is resolved for greedy evaluation ## macros @@ -40,6 +48,7 @@ template types ]## +{.push hint[XDeclaredButNotUsed]: off.} echo "############################ template" # copied from docs @@ -48,21 +57,23 @@ template `!=` (a, b: untyped): untyped = ## then replace a != b in the original with the below template ## i.e. assert(5 != 6) -> assert(not (5 == 6)) not (a == b) -assert(5 != 6) +# assert(5 != 6) # TODO(noah): throws in v2 # lazy evaluation of proc args const debug = true var xy = 4 -proc logEager(msg: string) {.inline.} = - ## msg arg is evaluted before the fn is evoked - if debug: stdout.writeLine(msg) -template logLazy(msg: string) = - ## the template is processed before msg arg - ## so if debug is false, msg wont be evaluted - if debug: stdout.writeLine(msg) - -logEager("x has the value: " & $xy) ## & and $ are expensive! only use with lazy templates -logLazy("x has the value: " & $xy) +# TODO(noah): stdout not system in v2 +# proc logEager(msg: string) {.inline.} = +# ## msg arg is evaluted before the fn is evoked +# if debug: stdout.writeLine(msg) +# template logLazy(msg: string) = +# ## the template is processed before msg arg +# ## so if debug is false, msg wont be evaluted +# if debug: stdout.writeLine(msg) + +# TODO(noah): requires updating both procs to v2 +# logEager("x has the value: " & $xy) ## & and $ are expensive! only use with lazy templates +# logLazy("x has the value: " & $xy) # copied from docs template blockRunner(please: bool, body: untyped): void = diff --git a/src/bookofnim/deepdives/tests.nim b/src/bookofnim/deepdives/tests.nim index 3e10be28..f1c59364 100644 --- a/src/bookofnim/deepdives/tests.nim +++ b/src/bookofnim/deepdives/tests.nim @@ -1,6 +1,6 @@ ## testing ## ======= -## [bookmark](https://nim-lang.org/docs/testament.html) +## [bookmark](https://nim-lang.github.io/Nim/testament.html) ##[ @@ -33,14 +33,14 @@ links - [testament src](https://github.com/nim-lang/Nim/tree/devel/testament) - high impact - [status fuzz testing](https://github.com/status-im/nim-testutils/tree/master/testutils/fuzzing) - - [testament: preferred testing tool](https://nim-lang.org/docs/testament.html) - - [testament: unit test boilerplate](https://nim-lang.org/docs/testament.html#writing-unitests) + - [testament: preferred testing tool](https://nim-lang.github.io/Nim/testament.html) + - [testament: unit test boilerplate](https://nim-lang.github.io/Nim/testament.html#writing-unitests) - [profiling and debugging](https://nim-lang.org/blog/2017/10/02/documenting-profiling-and-debugging-nim-code.html) - [nimble test docs](https://github.com/nim-lang/nimble#tests) - [valgrind dynamic analysis toolset](https://valgrind.org/) - niche - - [dr nim](https://nim-lang.org/docs/drnim.html) - - [unit tests (prefer testament)](https://nim-lang.org/docs/unittest.html) + - [dr nim](https://nim-lang.github.io/Nim/drnim.html) + - [unit tests (prefer testament)](https://nim-lang.github.io/Nim/unittest.html) - [Z3 proof engine](https://github.com/Z3Prover/z3) @@ -79,7 +79,7 @@ testament writing tests - "compile" only | "run" and compile | "reject" tests that dont throw expected errors - reject test if stdout fails sparsely match with expected stdout - examples that reflect specs & code - - [unittests examples](https://nim-lang.org/docs/testament.html#unitests-examples) + - [unittests examples](https://nim-lang.github.io/Nim/testament.html#unitests-examples) - expected output with tests grouped in blocks [tarray](https://github.com/nim-lang/Nim/blob/devel/tests/array/tarray.nim) - expected errors [inline with the code](https://github.com/nim-lang/Nim/blob/9a110047cbe2826b1d4afe63e3a1f5a08422b73f/tests/effects/teffects1.nim) - expected errors [based on exit code + output substitution](https://github.com/nim-lang/Nim/blob/devel/tests/assert/tassert.nim) diff --git a/src/bookofnim/helloworld/helloworld.nim b/src/bookofnim/helloworld/helloworld.nim index 10bc61a0..ba05e934 100644 --- a/src/bookofnim/helloworld/helloworld.nim +++ b/src/bookofnim/helloworld/helloworld.nim @@ -1,30 +1,25 @@ ## ## Hello world: my name is nim #version-2-0 ## ======================================== -## [bookmark](https://nim-lang.org/docs/manual.html#special-types) +## [bookmark](https://nim-lang.github.io/Nim/manual.html#special-types) ##[ ## TLDR -- only uses the implicitly imported system - - dont import (system, threads, channel) directly, theres some compiler magic to makem work - - threads, channels, templates, macros, effects, pragmas, os and io are in deepdives - newer nim versions seems to be getting more strict/better at catching programmer errors -- you should expect everything in nim is heavily overloaded - - hence only base syntax is shown and shouldnt be considered comprehensive in any form +- you can expect everything in nim is `almost` always + - heavily overloaded + - can be used as an expression + links ----- -- [system module](https://nim-lang.org/docs/system.html) -- [api design](https://nim-lang.org/docs/apis.html) -- [manual](https://nim-lang.org/docs/manual.html) +- [system module](https://nim-lang.github.io/Nim/system.html) +- [api design](https://nim-lang.github.io/Nim/apis.html) +- [manual](https://nim-lang.github.io/Nim/manual.html) - [tools dir](https://github.com/nim-lang/Nim/tree/devel/tools) - [status auditor docs](https://status-im.github.io/nim-style-guide/00_introduction.html) -TODOs ------ -- nim in action: copy all your notes starting from pg 40 - ## std library - pure libraries: do not depend on external *.dll/lib*.so binary - impure libraries: not pure libraries @@ -117,6 +112,9 @@ my preferences - when module A imports symbol B that exists in C and D - procs/iterators are overloaded, so no ambiguity - everything else must be qualified (c.b | d.b) if signatures are ambiguous +- module pseudo directories + - std: e.g. `import std/blah` imports from nims library to avoid identically named modules + - pkg: e.g. `import pkg/blah` imports nimble packages, but technically just the opposite of `std` pure modules ------------ @@ -140,9 +138,11 @@ import ------ - top-level symbols marked * from another module - are only allowed at the top level +- can except to limit whats imported + - the except list is not checked, allowing you to import future incompatible versions of a module - looks in the current dir relative to the imported file and uses the first match - else traverses up the nim PATH for the first match - - [search path docs](https://nim-lang.org/docs/nimc.html#compiler-usage-search-path-handling) + - [search path docs](https://nim-lang.github.io/Nim/nimc.html#compiler-usage-search-path-handling) .. code-block:: Nim import math # everything except private symbols import foo {.all.} # import everything @@ -240,6 +240,7 @@ keywords - its idiomatic nim to mutate it - discard - use a proc for its side effects but ignore its return value + - or prefix a triple quoted string to fake a comment statements ---------- @@ -268,7 +269,7 @@ visibility - force block scoped vars to global via {.global.} pragma ]## -{.push warning[UnusedImport]:off, hint[GlobalVar]:off .} +{.push warning[UnusedImport]:off .} import modules / [ blocks, ## block statements, @@ -278,7 +279,7 @@ import modules / [ routines, ## main types of procs structuredCollectionsOrdinals, ## ordered and collections of items structuredContainers, ## objects with named fields - traitsAdt, ## type traints and algebraic data types + typeSystem, ## classes, traits, adts, etc typeSimple, ## basic types userDefinedTypes, ## custom types with objects, tuples and enums variableGlobals, ## creating variables and globals diff --git a/src/bookofnim/helloworld/modules/blocks.nim b/src/bookofnim/helloworld/modules/blocks.nim index 6762fd38..46a74ed1 100644 --- a/src/bookofnim/helloworld/modules/blocks.nim +++ b/src/bookofnim/helloworld/modules/blocks.nim @@ -1,24 +1,23 @@ ## blocks ## ====== - ##[ ## TLDR - blocks have a () syntax but we skipped it as its not idiomatic nim in this context - new scope introduced after the : symbol, and ends when the indentention returns to previous level - named blocks can be exited specifically with `break blockName` + - Using a break in a unnamed block is deprecated and will soon be an error - like most other things, blocks can be expressions and assigned to a var -- see loopIterator.nim for closureScope blocks +- do notation, static and iterator closureScope can also be blocks, see elseware +- once blocks + - are executed once, the first time they're seen by the compiler links ----- -- [block statements](https://nim-lang.org/docs/manual.html#statements-and-expressions-block-statement) -- [block expressions](https://nim-lang.org/docs/manual.html#statements-and-expressions-block-expression) -- [once template](https://nim-lang.org/docs/system.html#once.t%2Cuntyped) - +- [block statements](https://nim-lang.github.io/Nim/manual.html#statements-and-expressions-block-statement) +- [block expressions](https://nim-lang.github.io/Nim/manual.html#statements-and-expressions-block-expression) +- [once template](https://nim-lang.github.io/Nim/system.html#once.t%2Cuntyped) -## once blocks -- are executed once, the first time they're seen by the compiler ]## {. hint[XDeclaredButNotUsed]:off .} diff --git a/src/bookofnim/helloworld/modules/exceptionHandlingDocs.nim b/src/bookofnim/helloworld/modules/exceptionHandlingDocs.nim index ef719fc2..d8ddd25f 100644 --- a/src/bookofnim/helloworld/modules/exceptionHandlingDocs.nim +++ b/src/bookofnim/helloworld/modules/exceptionHandlingDocs.nim @@ -8,60 +8,48 @@ - having `*` after - (like on this line) will break htmldocs rst parser - you must escape it with backticks `*` or backslash \* - error reported as `Error: '*' expected` - - pretty prints code in the html - `back ticks` and back slashes e.g. \*.nims can escape special chars + - pretty prints code in the html - if reusing rsts (e.g. for github readmes) - make sure to add an empty line before the first indented list item - IMO always externalize readme.rst files so their viewable in github & in html docs - exceptions - - all custom exceptions should ref a specific error/CatchableERror/Defect/and lastly Exception + - all custom exceptions should ref a specific CatchableError/Defect or lastly Exception - Exception is the base type for CatachableError (exceptions) and Defect (non catchable) - - has to be allocated on the heap (requires ref) because their lifetime is unknown + - has to be allocated on the heap because their lifetime is unknown - raise keyword for throwing an exception/defect - causes execution to cease until caught or program exits - e.g. `raise errInstance` - e.g. `raise newException(OSError, "Oops! did i do that?")` - raising without an error rethrows the previous exception - - compile with `--panics:on` to make defects unrecoverable + - compile with `--panics:on` to make errors defects at runtime instead of exceptions + - produces smaller binaries and enables more compiler optimizations - tracebacks: - each line in the stack track is a call to a procedure -- assert - - -d:danger or --asertions:off to remove from compilation - - --assertions:on to keep them in compiled output -- doAssert - - always on regardless of flags - - can be used to check for specific errors with `doAssertRaises(woop):` block - - useful for hard checks & design by contract -- drnim - - requires koch to be setup links ----- - other + - [documenting, profiling and debugging nim code](https://nim-lang.org/blog/2017/10/02/documenting-profiling-and-debugging-nim-code.html) + - [restructured text intro](https://docutils.sourceforge.io/docs/user/rst/quickstart.html) - [restructuredText wiki](https://docutils.sourceforge.io/docs/user/rst/quickref.html) - [status exception handling docs](https://nimbus.guide/auditors-book/02.3_correctness_distinct_mutability_effects_exceptions.html#enforcing-exception-handling) -- devel source - - [assertions](https://github.com/nim-lang/Nim/blob/devel/lib/std/assertions.nim) - - [exception and effect types](https://github.com/nim-lang/Nim/blob/devel/lib/system/exceptions.nim) - high impact - - [assertions](https://nim-lang.org/docs/assertions.html) - - [defect](https://nim-lang.org/docs/system.html#Defect) - - [docgen](https://nim-lang.org/docs/docgen.html) - - [documenting, profiling and debugging nim code](https://nim-lang.org/blog/2017/10/02/documenting-profiling-and-debugging-nim-code.html) - - [exception handling with defer](https://nim-lang.org/docs/manual.html#exception-handling-defer-statement) - - [exception hierarchy](https://nim-lang.org/docs/manual.html#exception-handling-exception-hierarchy) - - [exception](https://nim-lang.org/docs/system.html#Exception) - - [reStructuredText & markdown](https://nim-lang.org/docs/rst.html) - - [restructured text intro](https://docutils.sourceforge.io/docs/user/rst/quickstart.html) - - [runnable examples](https://nim-lang.org/docs/system.html#runnableExamples%2Cstring%2Cuntyped) + - [defect](https://nim-lang.github.io/Nim/system.html#Defect) + - [documentation tools](https://nim-lang.github.io/Nim/docgen.html) + - [all exceptions](https://github.com/nim-lang/Nim/blob/devel/lib/system/exceptions.nim) + - [exception handling with defer](https://nim-lang.github.io/Nim/manual.html#exception-handling-defer-statement) + - [exception hierarchy](https://nim-lang.github.io/Nim/manual.html#exception-handling-exception-hierarchy) + - [markdown & rst in nim](https://nim-lang.github.io/Nim/markdown_rst.html) + - [runnable examples](https://nim-lang.github.io/Nim/system.html#runnableExamples%2Cstring%2Cuntyped) - niche - - [drnim](https://nim-lang.org/docs/drnim.html) - - [segfaults module](https://nim-lang.org/docs/segfaults.html) + - [drnim](https://nim-lang.github.io/Nim/drnim.html) + - [segfaults module](https://nim-lang.github.io/Nim/segfaults.html) TODOs ----- - drnim tool -- debugger +- debugger (find where this is in the docs) - [try-except discussion](https://forum.nim-lang.org/t/9765) .. code-block:: Nim errorMessageWriter (var) called instead of stdmsg.write when printing stacktrace @@ -121,6 +109,7 @@ try/except/finally - like most things can be an expression and assigned to a var - the try + except must all be of the same type - if theres a finally, it must return void +- can be enclosed in (try...except) for a oneliner if no finally exists defer ----- @@ -128,11 +117,6 @@ defer - all statements after defer will be within an implicit try block - top level defers arent supported (must be within a block/proc/etc) -assert ------- -- useful for guard, pre & post conditions if using design by contract -- i think drnim even extends this further - ## documentation - starting a line with ## creates a title that appears in the left sidebar - both --- and === need to be the same length of whatever they're underlining @@ -175,6 +159,8 @@ echo "############################ documentation: runnableExamples" runnableExamples: var iam = GoodApplications(pubfield: "yes u are", prvfield: "I know I am") ## \ ## example of creating a good application + ## in nim source + ## runnableExamples are usually at the top of the file and can indeed be very long discard repr iam @@ -184,6 +170,7 @@ new(err) # instantiate it err.msg = "Oops! this is a bad error msg" type LearningError = object of CatchableError + ## I thought only refs can be raised? block howlong: try: @@ -213,7 +200,7 @@ echo maybeThrows(23) echo "############################ try/except/finally " if true: try: - let f: File = open "a file that doesnt exist" + raise newException(ValueError, "extended try except finally example") except OverflowDefect, ArithmeticDefect: echo "wrong error type" except ValueError as e: @@ -226,7 +213,7 @@ if true: echo "unknown exception" let e = getCurrentException() - msg = getCurrentExceptionMsg() + msg = getCurrentExceptionMsg() # this is likely what you want echo "Got exception ", repr(e), " with message ", msg finally: echo "Glad we survived this horrible day", @@ -253,33 +240,3 @@ proc deferExample: auto = echo deferExample() - - -echo "############################ assert" -# can be turned off -assert "a" == $'a' - -# is always turned on regardless of --assertions flag -doAssert 1 < 2, "failure msg" - -doAssertRaises KeyError: - raise newException(KeyError, "key error") - -when false: - doAssertRaises AssertionDefect: - raiseAssert "this msg" - -try: - # handles assertions in the current block - onFailedAssert msg: - # assert handler logic - let m = "assert handled: " & msg - raise newException(CatchableError, m) - # all assertions will be managed - doAssert 1 == 2, "1 !== 2" -except CatchableError as e: - echo e.msg - -# echo "############################ debugger" -# # Todo, find the debugger api in the docs somewhere -# # PFrame runtime frame of the callstack, part of the debugger api diff --git a/src/bookofnim/helloworld/modules/ifWhenCase.nim b/src/bookofnim/helloworld/modules/ifWhenCase.nim index 7b6a7d90..e3b8163c 100644 --- a/src/bookofnim/helloworld/modules/ifWhenCase.nim +++ b/src/bookofnim/helloworld/modules/ifWhenCase.nim @@ -9,13 +9,15 @@ - all can be used as expressions and the result assigned to a var - case statement branches should be listed in order of most expected -branching TODOs ---------------- -- [likely](https://nim-lang.org/docs/system.html#likely.t%2Cbool) -- [unlikely](https://nim-lang.org/docs/system.html#unlikely.t%2Cbool) -- an example of using when (and if?) inside an object constructor - - there are examples in the doc where when is used to optionally define props - - e.g. this file: https://github.com/nim-lang/Nim/blob/devel/lib/std/private/threadtypes.nim +links +----- +- [likely](https://nim-lang.github.io/Nim/system.html#likely.t%2Cbool) +- [unlikely](https://nim-lang.github.io/Nim/system.html#unlikely.t%2Cbool) + +TODOs +----- +- [rangeCheck(cond)](https://nim-lang.github.io/Nim/system.html#rangeCheck.t) + ## when - a compile time if statement - the condition MUST be a constant expression @@ -30,7 +32,10 @@ branching TODOs - can also use elif, else branches ]## -{.push hint[XDeclaredButNotUsed]:off .} +{.push + hint[XDeclaredButNotUsed]:off, + warning[UnreachableElse]:off +.} echo "############################ if" if not false: echo "true": else: echo "false" @@ -43,6 +48,14 @@ if 11 < 2 or (11 == 11 and 'a' >= 'b' and not true or false): elif "woop" == "poow": echo "poows arent woops" else: echo "you are the holy one" +let imTrue = true + +# useful with complex conditions +if likely(imTrue): + echo "hint to the compiler" +if unlikely(not imTrue): + echo "same thing" + echo "############################ when" # think this is as copypasta from docs when system.hostOS == "windows": @@ -61,7 +74,8 @@ when defined(posix) and not (defined(macosx) or defined(bsd)): when isMainModule: # true if the current file is compiled directly # useful for embedding logic (e.g. tests) that arent executed when the file is imported - assert true == true + echo "i am the mainfile" +else: echo "I have been imported" var whichVerse:string = when 1 < 2: "real world" else: "twitter verse" echo "i live in the " & whichVerse @@ -69,7 +83,7 @@ echo "i live in the " & whichVerse when false: # trick for commenting code echo "this code is never compiled and not required to be commented out" -# check if execution is compiletime or runtime (executable) +# check if execution is compiletime or runtime # cannot contain elif branches # must contain an else branch # cannot define new symbols @@ -103,9 +117,8 @@ when defined typeSupportBlah: echo "############################ case expressions" var numCase = 50.345 echo case numCase - of 2: "of 2 satisifes float 2.0" # ofs must a constant expression - # duplicate case labels are errors in v2 - # of 2.0: "is float 2.0" # if we switch to devel branch this throws duplicate + of 2: "of 2 satisifes float 2.0" # ofs must be a constant expression + # of 2.0: "is float 2.0" # duplicate case labels are errors in v2 of 5.0, 6.0: {.linearScanEnd.} # signify the end of likely scenarios "float is 5 or 6.0" diff --git a/src/bookofnim/helloworld/modules/loopsIterator.nim b/src/bookofnim/helloworld/modules/loopsIterator.nim index ad2c54a3..054be130 100644 --- a/src/bookofnim/helloworld/modules/loopsIterator.nim +++ b/src/bookofnim/helloworld/modules/loopsIterator.nim @@ -8,11 +8,11 @@ links ----- -- [iterators](https://nim-lang.org/docs/iterators.html) +- [iterators](https://nim-lang.github.io/Nim/iterators.html) - [iterator tut](https://nim-by-example.github.io/for_iterators/) -- [closureScope](https://nim-lang.org/docs/system.html#%7C%7C.i%2CS%2CT%2Cstaticstring) +- [closureScope](https://nim-lang.github.io/Nim/system.html#%7C%7C.i%2CS%2CT%2Cstaticstring) - [status iterator docs](https://nimbus.guide/auditors-book/02.1_nim_routines_proc_func_templates_macros.html#iterators) -- [system io iterators](https://nim-lang.org/docs/io.html#15) +- [system io iterators](https://nim-lang.github.io/Nim/io.html#15) TODOs ----- @@ -21,25 +21,34 @@ TODOs ## loop/iterator related procs - finished determine if a first class iterator has finished -- countup == `..` == `..<` (zero index countup) -- countdown == `..^` == `..^1` (zero index countdown) +- countup == `..` == `..<` (zero index countup) < is non inclusive upper bound +- countdown (zero index countdown) - items for i blah.items: always called if only 1 identifer is used - pairs for i,z blah.pairs: always called if two identifiers are used - low(blah) .. high(blah) - lines(somefile) each line in the file ## iterators -- inlined at the callsite when compiled +- routines that can be used in a for loop +- used for defining custom loops on complex objects +- {.inline.} iterators are inlined at the callsite compiled + - restrictions: + - only for templates, macros and other inline iterators + - cant be recursive + - uses yield instead of return - do not have the overhead from function calling - - prone to code bloat - - useful for defining custom loops on complex objects -- can be used as operators if you enclose the name in back ticks -- can be wrapped in a proc with the same name to accumulate the result and return it as a seq -- distinction with procs + - having more than 1 yield statement leads to code bloat + - the body of the for loop is inlined at EACH yield statement +- {.closure.} iterators + - restrictions: + - cannot be executed at compile time + - uses yield, use return to end early + - cant be used with js backend + - can be used as operators if you enclose the name in back ticks + - can be wrapped in a proc with the same name to accumulate the result and return it as a seq +- restrictions for both inline and closure iterators - can only be called from loops - - uses yield instead of return keyword - doesnt have an implicit result - - dont support recursion - cant be forward declared ]## @@ -104,7 +113,7 @@ while true: echo "correct finished usage: ", value # 1,2,3 echo "############################ for" -# loops over iterators +# looping over iterators for i in 1..5: echo "loop .. " & $i for i in 1 ..< 5: echo "loop ..< ", i for i in countup(0,10,2): echo "evens only ", i # alias for .. diff --git a/src/bookofnim/helloworld/modules/routines.nim b/src/bookofnim/helloworld/modules/routines.nim index 4990d131..1a002b0e 100644 --- a/src/bookofnim/helloworld/modules/routines.nim +++ b/src/bookofnim/helloworld/modules/routines.nim @@ -1,21 +1,15 @@ ## ## routines ## ======== -## [bookmark](https://nim-lang.org/docs/manual_experimental.html#do-notation) -# check how do is used in this screenshot: https://forum.nim-lang.org/t/9961 +## [bookmark](https://nim-lang.github.io/Nim/manual_experimental.html#do-notation) ##[ ## TLDR - routine: a symbol of kind proc, func, method, iterator, macro, template, converter - IMO this definition should also include tasks - - where to find which - - converters in globalVariables - - iterators in loopsIterators - - lambdas in sugar - - std & nimscript tasks in packaging - - templates in templateMacros - - other routine types are in this file - - routine exception tracking is in pragmasEffects +- callback parameters + - must be annoted with `{ .effectsOf consumerFnName .}` + - e.g. a sort fn thats always used with cmp function gotchas ------- @@ -29,14 +23,25 @@ links TODOs ----- -- [offsetOf](https://nim-lang.org/docs/system.html#offsetOf.t%2Ctypedesc%5BT%5D%2Cuntyped) -- [rangeCheck(cond)](https://nim-lang.org/docs/system.html#rangeCheck.t) -- [forward directions, couldnt get it to compile](https://nim-lang.org/docs/manual.html#var-return-type-future-directions) +- [offsetOf](https://nim-lang.github.io/Nim/system.html#offsetOf.t%2Ctypedesc%5BT%5D%2Cuntyped) +- [forward directions, couldnt get it to compile](https://nim-lang.github.io/Nim/manual.html#var-return-type-future-directions) - [read the status docs on this one](https://nimbus.guide/auditors-book/02.1.4_closure_iterators.html) - something to do with long lived ref objects & unreclaimable memory +- [using parameter statements](https://nim-lang.github.io/Nim/manual.html#statements-and-expressions-using-statement) +- [semi colins for visual distinction](https://nim-lang.github.io/Nim/manual.html#procedures) + - required when using using parameters +- [procedure type pragmas](https://nim-lang.github.io/Nim/manual.html#types-procedural-type) + - nimcall, closure, stdcall, cdecl, safecall, inline, fastcall, thiscall, syscall, noconv +## routines + +non overloadable routines +------------------------- +- declared, defined, definedInScope, compiles, sizeof, +- is, shallowCopy, getAst, astToStr, spawn, procCall -## procedures +procedures +---------- - returning things: (cant contain a yield statement) - use return keyword for early returns - result = sumExpression: enables return value optimization & copy elision @@ -45,36 +50,51 @@ TODOs - args passed to procs are eagerly evaluated - see templates for lazy evaluation -## openArray -- openArray[T] implemented as a pointer to the array data and a length field +funcs +----- +- alias for `proc blah() {. noSideEffect .}: ...` +- compiler throws error if reading/writing to global variables + - i.e. any var not a parameter/local +- allocating a seq/string does not throw an err + +closures +-------- +- can be created with proc expressions or do notation (see sugar) + +anonymous procs +--------------- +- dont have a name and surrounded by paranthesis + +## special routine parameters + +openArray[T, `$`] +----------------- +- implemented as a pointer to the array data and a length field - only used in proc signatures for accepting an array of any length - cant be used to with multidimensional array arguments + - can set any proc as the `$` for transformation - always index with int and starting at 0 - array args must match the param base type, index type is ignored - arrays and seqs are implicity converted for openArray params -## varargs +varargs[T] +---------- - enables passing a variable number of args to a proc param - the args are converted to an array if the param is the last param -## funcs -- alias for {. noSideEffect .} -- compiler throws error if reading/writing to global variables - - i.e. any var not a parameter/local -- allocating a seq/string does not throw an err - -## closures -- can be created with proc expressions or do notation - -## anonymous procs -- dont have a name and surrounded by paranthesis - +var parameters and return types +------------------------------- +- prefix a parameter/return type with `var` in signature enables mutations + - in param: proc can modify + - in return: consumer can modify +- are not nevessary for efficient parameter passing ]## + {.push hint[XDeclaredButNotUsed]: off .} echo "############################ procedures" proc pubfn*(): void = - echo "the * makes this fn public" + echo "the * makes this fn importable" # params with defaults dont requre a type proc eko(s = "Default value"): void = @@ -112,7 +132,7 @@ proc passedByReference(yy: var string): void = passedByReference zz proc redurn(this: string): string = - result &= this + result = this debugEcho redurn "Wtf is result value" # you can use explicitly return aswell @@ -124,11 +144,11 @@ proc mutate(this: var int): int = var num7 = 5 debugEcho mutate num7, num7.mutate, mutate(num7) + # you can return a var indicating the caller can mutate the return var gg = 0 -proc writeAccessToG(): var int = - result = gg -writeAccessToG() = 6 +proc writeAccessToG(x: var int): var int =x +writeAccessToG(gg) = 6 echo "g == 6 ", gg == 6 # noSideEffect pragma: statically ensures there are no side effects @@ -167,7 +187,7 @@ if `==`( `+`(3, 4), 7): echo "invoking operator as proc looks weird" # calling syntax impacts type compatability # ^ I cant seem to get this to throw an error # ^ read the docs (manual) and figure this out -# ^ @see https://nim-lang.org/docs/manual.html#types-procedural-type +# ^ @see https://nim-lang.github.io/Nim/manual.html#types-procedural-type proc greet(name: string): string = "Hello, " & name & "!" proc bye(name: string): string = @@ -227,9 +247,6 @@ proc runFn(a: string, fn: proc(x: string): string): string = fn a echo runFn("with this string", proc (x: string): string = "received: " & x) -# closures with do notation -echo runFn("with another string") do (x: string) -> string: "another: " & x - # anonymous proc # var someName = ( proc (params): returnType = "woop") diff --git a/src/bookofnim/helloworld/modules/structuredCollectionsOrdinals.nim b/src/bookofnim/helloworld/modules/structuredCollectionsOrdinals.nim index 7da48914..1c024b97 100644 --- a/src/bookofnim/helloworld/modules/structuredCollectionsOrdinals.nim +++ b/src/bookofnim/helloworld/modules/structuredCollectionsOrdinals.nim @@ -11,16 +11,15 @@ - containers of fields: e.g. objects, tuples, hashtables - collections of items: e.g. sequences, arrays, char, sub/ranges, tables - ordinal types - - ordinals are values that can be orderly counted + - ordinals are values that are countable and ordered, with a smallest & highest value - enums, u/integers, bool - - are countable and ordered, with a smallest & highest value - FYI about low & high procs - should only be used with types not values links ----- - [nim by example: arrays](https://nim-by-example.github.io/arrays/) -- [table constructor](https://nim-lang.org/docs/manual.html#statements-and-expressions-table-constructor) +- [table constructor](https://nim-lang.github.io/Nim/manual.html#statements-and-expressions-table-constructor) ## structured: collections - cstringArray @@ -28,11 +27,6 @@ links ## array - list of a static number of items - similar to C arrays but more memory safety - -array procs ------------ -- array[n, T] fixed-length dimensionally homogeneous -- array, openArray, UncheckedArray, varargs - the array size is encoded in its type - to pass an array to a proc its signature must specify the size and type - array access is always bounds checked (theres a flag to disable) @@ -40,6 +34,10 @@ array procs - each array dimension must have the same type, - nested (multi-dimensional) arrays can have different types than their parent +array types +----------- +- array[n, T] fixed-length dimensionally homogeneous + array like ---------- - openArray[T] a procs parameter that accepts an array/seq of any size but only of 1 dimension @@ -72,6 +70,7 @@ table - both use the same syntax, only the context changes - 0 .. 2 --> inclusive .. inclusive - 0 .. ^1 --> ^ counts backwards, ^1 includes the last element, ^2 doesnt + range ----- - range[T] generic constructor for range @@ -337,9 +336,10 @@ echo "is {1,2,3} a subset of {1,2,3} ", globalset1 <= {1,2,3} echo "is {1,2,3} a strict subset of y ", globalset1 < {1,2,3} echo "the cardinality of {1,2,3} is ", card globalset1 -var globalset11 = deepCopy globalset1 -globalset11.excl({2}) -echo "remove {2} from {1,2,3} ", globalset11 +# TODO(noah): dunno throws in v2 +# var globalset11 = deepCopy globalset1 +# globalset11.excl({2}) +# echo "remove {2} from {1,2,3} ", globalset11 echo "############################ general logic" diff --git a/src/bookofnim/helloworld/modules/traitsAdt.nim b/src/bookofnim/helloworld/modules/traitsAdt.nim deleted file mode 100644 index 8e2612ae..00000000 --- a/src/bookofnim/helloworld/modules/traitsAdt.nim +++ /dev/null @@ -1,203 +0,0 @@ -## algebraic data types and traits -## =============================== - -##[ -## TLDR -- algebraic data types and catchall for nims type system - -links ------ -- [type classes](https://nim-lang.org/docs/manual.html#generics-type-classes -- [implicit generics](https://nim-lang.org/docs/manual.html#generics-implicit-generics) -- [type bound operators](https://nim-lang.org/docs/manual.html#procedures-type-bound-operators) -- [object variants](https://nim-lang.org/docs/manual.html#types-object-variants) - -TODOs ------ -- read through the scala notes and try to replicate the algebraic DTs -- move all the type logic stuff in here -- create a test file -- add readme -- add to bookofnim -- metatype examples -- type bound operator examples (and should probably reread those docs) -- probably should reread the typedesc docs -- [symbol lookups in generics](https://nim-lang.org/docs/manual.html#generics-symbol-lookup-in-generics) - - mixin statement - - bind statement - - delegating bind statements -- object variants: reread the docs - - using the dereferencing operator to reassign a case objects fields after instantiation - - differences with case + elif branches in the case statement - - enums vs range type for the discrimator field -- generics and the method call syntax - - theres a `[:X]` syntax that doesnt conflict with the method call syntax (blah.method) - - [docs](https://nim-lang.org/docs/manual.html#procedures-method-call-syntax) - - [forum post](https://forum.nim-lang.org/t/10125) - -## metatypes -- untyped lookup symbols & perform type resolution after the expression is interpreted & checked - - i.e. expression is lazily resolved to its value (for templates) - - use to pass a block of statements -- typed: semantic checker evaluates and transforms args before expression is interprted & checked - - an expression that is [eagerly] resolved to its value (for templates) - - i.e. whenever u set a type in a signature its resolved immediately -- typedesc a type description -- void absence of any type, generally used as proc return type - -## type bound operators -- a proc or func whose name starts with = but isnt an operator -- unrelated to propertie setters which end in = despite syntax similarities - - x =copy y - - x =destroy y Generic destructor implementation - - x =sink y Generic sink implementation - - x =trace y Generic trace implementation - -## type classes -- pseudo type that can be used to match via the is operator -- object, tuple, enum, proc, ref, ptr, var, distinct, array, set, seq auto -- in addition, every generic type creates a type class of the same name - -## typedesc -- since nim treats the names of types as regular values in certain contexts in the compilation phase -- typedesc is a generic type for all types denoting the type class of all types -- procs using typedesc params are implicitly generic - -## object variants -- preferred over an object hierarchy with multiple levels when simple variants suffice -- are tagged unions, which use an enum to discrimate between variant - - generally a field called `kind` is set to SomeEnum, whose fields determine the branch -- also called `case objects` in the docs - -variant pragmas ---------------- -- uncheckedAssign disables re-assignment restrictions - -## generics -- abc - -]## - -{.push hint[XDeclaredButNotUsed]:off .} -echo "############################ type aliases" -type - BigMoney* = int # <- can be used wherever int is expected -echo 4 + BigMoney(2000) - -type StrOrInt = string|int -let thizString: StrOrInt = "1" -let thisInt: StrOrInt = 1 - -echo "could be a string or an int ", thizString, thisInt - -echo "############################ type aliases distinct" -type - BiggerMoney = distinct BigMoney - BiggestMoney {.borrow: `.`.} = distinct BigMoney # borrows all procs -# echo 10 + FkUMoney(100) # type mismatch - -echo "############################ metatypes" -# todo - - -echo "############################ type bound operators" -# todo - - -echo "############################ generics" -# parameterize procs, iterators or types -# parameterized: Thing[T] -# static constrained: Thing[T: x or y] will resolve to x or y staticlly, and remain so at runtime -# ^ i.e. a var Z cant change between x & y after semantic resolution phase -# generic params are compiled separately for each unique value/combination of such -# ^ generic params should not be overused (IMO) as it will lead to code bloat - -# generic procs -proc wtf[T](a: T): auto = - # the is operator is useful for type specialization within generic code - if T is SomeNumber: result = "wtf is this num " & $a - elif T is string: result = "wtf is this string " & $a - else: result = "wtf is this thing " & $typeof a - -echo wtf "yo" -echo wtf 2 -echo wtf ("tup", "el") - -# generic proc method call syntax -proc foo[T](i: T) = - echo i, " using method call syntax" -var ii: int -# ii.foo[int]() # Error: expression 'foo(i)' has no type (or is ambiguous) -ii.foo[:int]() # Success - - -echo "############################ type classes" -# even tho myRecord is tuple, it doesnt extend from tuple -# so we have to add typeof myRecord explicitly to RecordType -var myRecord: tuple[wtf: string] = (wtf: "yo") - -# this matches against tuple, we dont need to add it to the RecordType -type OtherRecord = tuple - wtf: string - -# from docs -# create a type class that will match all tuple and object types -type RecordType = (typeof myRecord) or object | tuple # or and | are interchangable -# an implicitly generic procedure: -# each param is bound ONCE to a concrete subtype of T (object|tupe|myRecord) -proc printFields[T: RecordType](rec: T) = # same as printFields(rec: RecordType) - for key, value in fieldPairs(rec): - echo key, " = ", value - -var utherRecord: OtherRecord = (wtf: "yo2") - -printFields(myRecord) -printFields(utherRecord) - -# bind many types use distinct to enable params to bind to ANY of the concrete subtypes of T -# T can be pulled out like before into a type declaration -# without the distinct both first and second would HAVE to be of the same type, because it binds once -proc fieldsPrint[T: distinct tuple | object](first, second: T) = - if typeof first is typeof second: echo "got two of the same" - else: echo "got a tuple and object" - -echo "############################ typedesc" -# docs -template declareVariableWithType(T: typedesc, value: T) = - var x: T = value - -declareVariableWithType(int, 42) - - -echo "############################ object variants" - -type - LanguageKind = enum # consumers can create these kinds of object variants - typescript, nimlang, shell - Language = ref LanguageObj # uses the fields defined in the object - LanguageObj = object # tagged unions - # shared fields - stack: string - appName: string - # each variant must have distinct fields - case kind: LanguageKind # discriminated by this field - of typescript: - bun: bool - of nimlang: - c: bool - of shell: - bash: bool - -# create a new case object -var fireTeam = Language(kind: nimlang, stack: "allstack", appName: "nirvai" ) -var webTeam = Language(kind: typescript, stack: "fullstack", appName: "nirvaiWeb") -var opsTeam = Language(kind: shell, stack: "network", appName: "nirvConnect") - -type - FakeOption = object - case key: bool - of true: val: string - else: discard - -# create a fake option -var myOpt = FakeOption(key: true, val: "has a value") diff --git a/src/bookofnim/helloworld/modules/typeSimple.nim b/src/bookofnim/helloworld/modules/typeSimple.nim index 8494f45b..d1b4bb48 100644 --- a/src/bookofnim/helloworld/modules/typeSimple.nim +++ b/src/bookofnim/helloworld/modules/typeSimple.nim @@ -5,7 +5,7 @@ ##[ ## TLDR - Conversion between int and int32 or int64 must be explicit except for string literals. -- stay away from [blah% operators in practice](https://nim-lang.org/docs/manual.html#types-preminusdefined-integer-types) +- stay away from [blah% operators in practice](https://nim-lang.github.io/Nim/manual.html#types-preminusdefined-integer-types) - % are mainly for backwards compatibility with previous nim versions - generally procs that work for strings work for chars - generally strings can use any seq proc for manipulation @@ -14,8 +14,8 @@ links ----- -- [wide strings](https://nim-lang.org/docs/widestrs.html) -- [dollars](https://nim-lang.org/docs/dollars.html) +- [wide strings](https://nim-lang.github.io/Nim/widestrs.html) +- [dollars](https://nim-lang.github.io/Nim/dollars.html) ## string - value semantics @@ -67,7 +67,8 @@ boolean procs - ord(c) Return int value of a character - a & b Concatenate two strings - s.add(c) Add character to the string -- $ Convert various types to string +- $ Convert various types to string (except float) +- repr convert anything to a string - substr - find returns index of char in string - contains true/false @@ -157,7 +158,21 @@ let y1: int8 = int8('a') # 'a' == 97'i8 z1: float = 2.5 # int(2.5) rounds down to 2 sum: int = int(x1) + int(y1) + int(z1) # sum == 100 - +discard """ + 'i8 int8 + 'i16 int16 + 'i32 int32 + 'i64 int64 + 'u uint + 'u8 uint8 + 'u16 uint16 + 'u32 uint32 + 'u64 uint64 + 'f float32 + 'd float64 + 'f32 float32 + 'f64 float64 +""" const b = 100 @@ -173,7 +188,7 @@ echo "abs -1 is ", abs -1 const e: uint8 = 100 f = 100'u8 -echo "4 / 2 === ", num2 / num1 # / always returns a float +echo "4 / 2 === ", (num2 / num1).repr # echo "4 div 2 === ", num2 div num1 # always returns an int @@ -187,7 +202,7 @@ const i = 4e7 # 4 * 10^7 l = 1.0e9 m = 1.0E9 -echo "4.0 / 2.0 === ", num4 / num3 +# echo "4.0 / 2.0 === ", num4 / num3 # TODO(noah): throws in v2 echo "4.0 div 2.0 === ", "gotcha: div is only for integers" echo "conversion acts like javascript floor()" echo "int(4.9) div int(2.0) === ", int(num5) div int(num3) diff --git a/src/bookofnim/helloworld/modules/typeSystem.nim b/src/bookofnim/helloworld/modules/typeSystem.nim new file mode 100644 index 00000000..b31ebda1 --- /dev/null +++ b/src/bookofnim/helloworld/modules/typeSystem.nim @@ -0,0 +1,276 @@ +## nims type system +## ================ + +##[ +## TLDR +- the potential for effectively using typedesc deserves multiple readings of the docs +- not understanding bind once vs bind many can produce interesting bugs in your code +- to cast a float to a string, use myFloat.repr, `$` doesnt work + +links +----- +- other + - [converters](https://nimbus.guide/auditors-book/02.1_nim_routines_proc_func_templates_macros.html#converter) +- high impact + - [generic inference restrictions](https://nim-lang.github.io/Nim/manual.html#generics-generic-inference-restrictions) + - [generics](https://nim-lang.github.io/Nim/manual.html#generics) + - [implicit generics](https://nim-lang.github.io/Nim/manual.html#generics-implicit-generics) + - [special types](https://nim-lang.github.io/Nim/manual.html#special-types) + - [special types](https://nim-lang.github.io/Nim/manual.html#special-types) + - [type bound operators](https://nim-lang.github.io/Nim/manual.html#procedures-type-bound-operators) + - [type classes](https://nim-lang.github.io/Nim/manual.html#generics-type-classes + - [typedesc](https://nim-lang.github.io/Nim/manual.html#special-types-typedesc-t) + - [typeinfo](https://nim-lang.github.io/Nim/typeinfo.html) + - [view types](https://nim-lang.github.io/Nim/manual_experimental.html#view-types) + +TODOs +----- +- [out parameters](https://nim-lang.github.io/Nim/manual_experimental.html#strict-definitions-and-nimout-parameters-nimout-parameters) +- read through the scala notes and try to replicate the algebraic data types +- move all the type logic stuff in here +- metatype examples +- type bound operator examples (and should probably reread those docs) +- probably should reread the typedesc docs +- [symbol lookups in generics](https://nim-lang.github.io/Nim/manual.html#generics-symbol-lookup-in-generics) + - mixin statement + - bind statement + - delegating bind statements +- generics and the method call syntax + - theres a `[:X]` syntax that doesnt conflict with the method call syntax (blah.method) + - [docs](https://nim-lang.github.io/Nim/manual.html#procedures-method-call-syntax) + - [forum post](https://forum.nim-lang.org/t/10125) +- [example with is operator for generics](https://nim-lang.github.io/Nim/manual.html#generics-is-operator) + +## metatypes +- untyped lookup symbols & perform type resolution after the expression is interpreted & checked + - i.e. expression is lazily resolved to its value (for templates) + - use to pass a block of statements +- typed: semantic checker evaluates and transforms args before expression is interprted & checked + - an expression that is [eagerly] resolved to its value (for templates) + - i.e. whenever u set a type in a signature its resolved immediately +- typedesc a type description +- void absence of any type, generally used as proc return type + +## type bound operators +- a proc or func starting with = but isnt an operator (yet still uses backticks in signature) + - is always visible to the type, i.e. regardless of visibility of the definition + - i.e. are bound to the Type and lifted to global scope +- unrelated to propertie setters which end in = despite syntax similarities + - =copy + - =destroy Generic destructor implementation + - =sink Generic sink implementation + - =trace Generic trace implementation + - =deepcopy + - =wasMoved + +## type classes +- pseudo type that can be used to match via the is operator +- are compile-time constraints enforced at instantiation, not dynamically at runtime +- in addition, every generic type creates a type class of the same name + - native: object, tuple, enuim, proc, iterator, ref, ptr, var, distinct, array, set, seq, auto +- can be conbined, e.g. `type RecordType = (object or tuple)` or as `object | tuple` +- will be intantiated (overloaded) once for each unique combination used within the program + - bind once types: each are bound once per concrete type + - bind many types: each are bound for every concrete type if `distinct|typedesc` is applied + +typedesc +-------- +- nim treats the names of types as regular values in certain contexts in the compilation phase +- typedesc is a generic type for all types denoting the type class of all types + - i.e. all types are really typedesc[blah], e.g. int == typedesc[int] +- procs using typedesc params are implicitly generic + - i.e. `p(a: typedesc)` == `p[T](a: typedesc[T])` + - i.e. `p(a: typedesc; b:a)` == `p[T](a: typedesc[T]; b: T)` == `p(int, 4)` + +static[T] +--------- +- must be constant expressions +- are treated as generic parameters, thus compiled for each unique type T +- proc parameters can also be static, +- expressions (e.g. proc invocations) can be coereced to static(blah()) for compile time evalution + +## converters +- routine that (re)defines conversion between two types +- can be explicitly invoked for readability +- converter chaining is not automatic + - i.e. a > b > c exist, but a > c does not occur automatically + +inspection +---------- +- type(x): retrieve the type of x, discouraged should use typeof +- typeof(x, mode = typeofIter): retrieve the type of x +- typeOfProc: retrieve the result of a proc, i.e. typeof x, typeOfProc +- TypeofMode: enum[typeofProc|typeofIter] second param to typeof + +## generics +- abc + +## views +- a symbol (let, var, const,etc) that has a view type + - views borrow their values from some other location + - ensures `thisView = thisLocation` + - thisView doesnt outlive thisLocation + - thisLocation isnt mutated +- any type that is/contains + - `lent T` view into T + - `openArray[T]` + - e.g.: openArray[byte] | lent string | Table[openArray[char], int] +- except if + - constructed via ptr / proc + - e.g. proc (x: openArray[T]) | ptr openArray[char] | ptr array[4, lent int] +- path expressions: the source for thisLocation must be + - accessor like e[i] + - pointer dereference like e[] + - type conversion/cast like T(e) | cast[T](e) + - procs that return view types +]## + +{.push hint[XDeclaredButNotUsed]:off .} +echo "############################ type aliases" +type + BigMoney* = int # <- can be used wherever int is expected +echo 4 + BigMoney(2000) + +type StrOrInt = string|int +let thizString: StrOrInt = "1" +let thisInt: StrOrInt = 1 + +echo "could be a string or an int ", thizString, thisInt + +echo "############################ type aliases distinct" +type + BiggerMoney = distinct BigMoney + BiggestMoney {.borrow: `.`.} = distinct BigMoney # borrows all procs +# echo 10 + FkUMoney(100) # type mismatch + +echo "############################ metatypes" +# todo + + +echo "############################ type bound operators" +# todo + + +echo "############################ generics" +# parameterize procs, iterators or types +# parameterized: Thing[T] +# 3 constrained: Thing[T: x or y] will resolve to x or y staticlly, and remain so at runtime +# ^ i.e. a var Z cant change between x & y after semantic resolution phase +# generic params are compiled separately for each unique value/combination of such +# ^ generic params should not be overused (IMO) as it will lead to code bloat + +# generic procs +proc wtf[T](a: T): auto = + # the is operator is useful for type specialization within generic code + if T is SomeNumber: result = "wtf is this num " & $a + elif T is string: result = "wtf is this string " & $a + else: result = "wtf is this thing " & $typeof a + +echo wtf "yo" +echo wtf 2 +echo wtf ("tup", "el") + +# generic proc method call syntax +proc foo[T](i: T) = + echo i, " using method call syntax" +var ii: int +# ii.foo[int]() # Error: expression 'foo(i)' has no type (or is ambiguous) +ii.foo[:int]() # Success + + +echo "############################ type classes" +# even tho myRecord is tuple, it doesnt extend from tuple +# so we have to add typeof myRecord explicitly to RecordType +var myRecord: tuple[wtf: string] = (wtf: "yo") + +# this matches against tuple, we dont need to add it to the RecordType +type OtherRecord = tuple + wtf: string + +# from docs +# create a type class that will match all tuple and object types +type RecordType = (typeof myRecord) or object | tuple # or and | are interchangable +# an implicitly generic procedure: +# each param is bound ONCE to a concrete subtype of T (object|tupe|myRecord) +proc printFields[T: RecordType](rec: T) = # same as printFields(rec: RecordType) + for key, value in fieldPairs(rec): + echo key, " = ", value + +var utherRecord: OtherRecord = (wtf: "yo2") + +printFields(myRecord) +printFields(utherRecord) + +# bind many types use distinct to enable params to bind to ANY of the concrete subtypes of T +# T can be pulled out like before into a type declaration +# without the distinct both first and second would HAVE to be of the same type, because it binds once +proc fieldsPrint[T: distinct tuple | object](first, second: T) = + if typeof first is typeof second: echo "got two of the same" + else: echo "got a tuple and object" + +echo "############################ typedesc" +# docs +template declareVariableWithType(T: typedesc, value: T) = + var x: T = value + +declareVariableWithType(int, 42) + + +echo "############################ converters (implicit type conversion procs)" +type Option[T] = object + case hasValue: bool + of true: + value: T + else: + discard +let aa = Option[int](hasValue: true, value: 1) +let bb = Option[int](hasValue: true, value: 2) + +# TODO(noah) strict case objects +# converter get[T](x: Option[T]): T = +# ## create an implicit conversion for Option[T] +# ## now Option[int] + Option[int] works +# x.value +# echo "adding two options ", aa + bb + +# copied from docs +# bad style ahead: Nim is not C. +converter toBool(x: int): bool = x != 0 +if 4: + echo "compiles because implicit conversxion converts int to bool" + +echo "############################ type inference" +var somevar: seq[char] = @['n', 'o', 'a', 'h'] +var othervar: string = "" +echo "somevar is seq? ", somevar is seq +echo "somevar is seq[char]? ", "throws err when adding subtype seq[char]" +echo "somevar isnot string? ", somevar isnot string + + +type MyType = ref object of RootObj +var instance: MyType = MyType() + +echo "is instance of MyType ", instance of MyType + +echo "############################ static" + +static: + echo "this at compile time" + +echo "a static bool ", static[bool](1 == 1) + +let myStaticVar = static(1 + 2) ## \ + ## static(x): force the compile-time evaluation of the given expression +echo "my static var", myStaticVar + +echo "############################ type casts" +var myInt = 10 + +proc doubleFloat(x: float): float = x * x +# echo "cast int to a float ", doubleFloat(cast[float](myInt)) # TODO(noah): throws in v2 + +echo "############################ type inspection" +# assert typeof("a b c".split) is string +# assert typeof("a b c".split, typeOfProc) is seq[string] +let x: string = "ima string" +let y: typeof(x) = "ima also a string" diff --git a/src/bookofnim/helloworld/modules/userDefinedTypes.nim b/src/bookofnim/helloworld/modules/userDefinedTypes.nim index 0dc18c2f..23724a92 100644 --- a/src/bookofnim/helloworld/modules/userDefinedTypes.nim +++ b/src/bookofnim/helloworld/modules/userDefinedTypes.nim @@ -23,17 +23,23 @@ links ----- -- [distinct type aliases](https://nim-lang.org/docs/manual.html#types-distinct-type) -- [inheritance](https://nim-lang.org/docs/manual.html#type-relations) -- [reference and pointer types](https://nim-lang.org/docs/manual.html#types-reference-and-pointer-types) - +- [distinct type aliases](https://nim-lang.github.io/Nim/manual.html#types-distinct-type) +- [inheritance](https://nim-lang.github.io/Nim/manual.html#type-relations) +- [reference and pointer types](https://nim-lang.github.io/Nim/manual.html#types-reference-and-pointer-types) +- [object variants](https://nim-lang.github.io/Nim/manual.html#types-object-variants) TODOs ------ -- add a testfile -- import in bookofnim.nim -- update readme - +- [strict case objects](https://nim-lang.github.io/Nim/manual_experimental.html#strict-case-objects) +- [concepts](https://nim-lang.github.io/Nim/manual_experimental.html#concepts) +- [setters for private fields](https://nim-lang.github.io/Nim/manual.html#procedures-properties) +- [procCall i.e. super](https://nim-lang.github.io/Nim/manual.html#methods-inhibit-dynamic-method-resolution-via-proccall) +- object variants: reread the docs + - using the dereferencing operator to reassign a case objects fields after instantiation + - differences with case + elif branches in the case statement + - enums vs range type for the discrimator field +- an example of using when (and if?) inside an object constructor + - there are examples in the doc where when is used to optionally define props + - e.g. this file: https://github.com/nim-lang/Nim/blob/devel/lib/std/private/threadtypes.nim ## base types - used to construct custom types @@ -111,6 +117,16 @@ multi-methods - however they are still ambiguous because of inheritance - you have to use --multimethods:on when compiling +## object variants +- preferred over an object hierarchy with multiple levels when simple variants suffice +- are tagged unions, which use an enum to discrimate between variant + - generally a field called `kind` is set to SomeEnum, whose fields determine the branch +- also called `case objects` in the docs + +variant pragmas +--------------- +- uncheckedAssign disables re-assignment restrictions + ## recursive types - objects, tuples and ref objects that recursively depend on each other - must be declared within a single type section @@ -127,9 +143,10 @@ echo "############################ object" type Computer = object - os: string + os: string = "ubuntu" de: string wm: string + name = "default values in v2! type inferred" type DistroObj = object @@ -151,6 +168,9 @@ proc `prv=`*(x: var SomeObj, v: string) {.inline.} = proc `prv`*(x: SomeObj): string {.inline.} = x.prv var myobj = SomeObj(pub: "pub field") +proc `$`(x: SomeObj): string = + ## overload $ for SomeObj + x.pub & " " & x.prv echo "myobj before setting: ", myobj myobj.prv= "another value" @@ -168,14 +188,17 @@ proc `[]=`* (v: var Vector, i: int, value: float) = of 0: v.x = value of 1: v.y = value of 2: v.z = value - else: assert(false) + # else: assert(false) # TODO(noah): assert isnt system in v2 + else: discard # see above + proc `[]`* (v: Vector, i: int): float = + result = 0 # getter case i of 0: result = v.x of 1: result = v.y of 2: result = v.z - else: assert(false) + else: discard echo "############################ tuple" @@ -289,7 +312,7 @@ let people2 = SomeoneRef(name: "npc", bday: "before noah", age: 1) -method baseMethod(self: SomeoneRef): bool {.base.} = +method baseMethod(self: SomeoneRef): void {.base.} = # override this base method raise newException(CatchableError, "Method without implementation override") @@ -335,9 +358,12 @@ type PlusExpr = ref object of Expression a, b: Expression +# TODO(noah): v2 fkn v2 or the strict config.nim switches # watch out: 'eval' relies on dynamic binding -method eval(e: Expression): int {.base.} = # <-- its for the base type - # override this base method +method eval(e: Expression): int {.base.} = + result = 0 + ## example base method that simply quits with a message for the consumer + ## you can force call the base method via procCall someMethod() quit "to override!" # use methods because at runtime we need to know the type method eval(e: Literal): int = e.x @@ -345,10 +371,8 @@ method eval(e: PlusExpr): int = eval(e.a) + eval(e.b) # these procs dont need dynamic binding proc newLit(x: int): Literal = Literal(x: x) proc newPlus(a, b: Expression): PlusExpr = PlusExpr(a: a, b: b) - echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) -# you can force call the base method via procCall someMethod(a,b) echo "############################ multi-methods" # copied from docs @@ -357,7 +381,7 @@ type Unit = ref object of Thing x: int # accepts any Thing -method collide(a, b: Thing) {.inline.} = +method collide(a, b: Thing) {.inline, base.} = quit "to override!" # note the order method collide(a: Thing, b: Unit) {.inline.} = @@ -384,3 +408,37 @@ type name: string # the symbol's name line: int # the line the symbol was declared in code: Node # the symbol's abstract syntax tree + + +echo "############################ object variants" + +type + LanguageKind = enum # consumers can create these kinds of object variants + typescript, nimlang, shell + Language = ref LanguageObj # uses the fields defined in the object + LanguageObj = object # tagged unions + # shared fields + stack: string + appName: string + # each variant must have distinct fields + case kind: LanguageKind # discriminated by this field + of typescript: + bun: bool + of nimlang: + c: bool + of shell: + bash: bool + +# create a new case object +var fireTeam = Language(kind: nimlang, stack: "allstack", appName: "nirvai" ) +var webTeam = Language(kind: typescript, stack: "fullstack", appName: "nirvaiWeb") +var opsTeam = Language(kind: shell, stack: "network", appName: "nirvConnect") + +type + FakeOption = object + case key: bool + of true: val: string + else: discard + +# create a fake option +var myOpt = FakeOption(key: true, val: "has a value") diff --git a/src/bookofnim/helloworld/modules/variableGlobals.nim b/src/bookofnim/helloworld/modules/variableGlobals.nim index 2cf31b9d..e696ae8c 100644 --- a/src/bookofnim/helloworld/modules/variableGlobals.nim +++ b/src/bookofnim/helloworld/modules/variableGlobals.nim @@ -1,26 +1,23 @@ ## ## variables and globals ## ===================== +## redo this entire file, likely just name it globals or something ##[ ## TLDR -- catchall for global keywords/procs/types/etc not specified in other files - anything like `BLAH=` can be written `BLAH =` - the former enables you to define/overload operators via 'proc `woop=`[bloop](soop): doop = toot' -- converts are listed here because their purpose is implicit type coercion -- additional type features are covered in structuredContainers.nim - you can call clear on pretty much anything links ----- -- [system vars](https://nim-lang.org/docs/system.html#8) -- [typeinfo](https://nim-lang.org/docs/typeinfo.html) -- [converters](https://nimbus.guide/auditors-book/02.1_nim_routines_proc_func_templates_macros.html#converter) -- [special types](https://nim-lang.org/docs/manual.html#special-types) +- [system vars](https://nim-lang.github.io/Nim/system.html#8) TODOs ----- - blah.reset a thing to its default value +- [type conversions](https://nim-lang.github.io/Nim/manual.html#statements-and-expressions-type-conversions) +- [type casts](https://nim-lang.github.io/Nim/manual.html#statements-and-expressions-type-casts) ## var - runtime mutable global var @@ -69,12 +66,6 @@ TODOs - toOpenArray - toOpenArrayByte -## type inspection -- type(x): retrieve the type of x, discouraged should use typeof -- typeof(x, mode = typeofIter): retrieve the type of x -- typeOfProc: retrieve the result of a proc, i.e. typeof x, typeOfProc -- TypeofMode: enum[typeofProc|typeofIter] second param to typeof - ## echo/repr - roughly equivalent to writeLine(stdout, x); flushFile(stdout) - available for the JavaScript target too. @@ -106,9 +97,6 @@ echo "autoInt labeled auto but its type is ", type(autoInt) echo "############################ variable logic" -# shallow copy isnt defined for arc/orc -# shallow(blah) marks blah as shallow for optimization, subsequent assignments wont deep copy -# shallowCopy(x, y) copies y into x let someString = "some string" var d33pcopy: string ## \ @@ -163,60 +151,6 @@ echo "quit the program with quit(n) or quit(msg, n)" echo "############################ global let" # nimvm: bool true in Nim VM context and false otherwise; valid for when expressions -echo "############################ type casts" -var myInt = 10 - -proc doubleFloat(x: float): float = x * x -echo "cast int to a float ", doubleFloat(cast[float](myInt)) - -echo "############################ type support" -# assert typeof("a b c".split) is string -# assert typeof("a b c".split, typeOfProc) is seq[string] - -echo "a static bool ", static[bool](1 == 1) - -let myStaticVar = static(1 + 2) ## \ - ## static(x): force the compile-time evaluation of the given expression -echo "my static var", myStaticVar - -static: - # can also be used as a block - echo "at compile time" -echo "############################ converters (implicit type conversion procs)" -type Option[T] = object - case hasValue: bool - of true: - value: T - else: - discard -let aa = Option[int](hasValue: true, value: 1) -let bb = Option[int](hasValue: true, value: 2) - -converter get[T](x: Option[T]): T = - ## create an implicit conversion for Option[T] - ## now Option[int] + Option[int] works - x.value -echo "adding two options ", aa + bb - -# copied from docs -# bad style ahead: Nim is not C. -converter toBool(x: int): bool = x != 0 -if 4: - echo "compiles because implicit conversxion converts int to bool" - -echo "############################ type inference" -var somevar: seq[char] = @['n', 'o', 'a', 'h'] -var othervar: string = "" -echo "somevar is seq? ", somevar is seq -echo "somevar is seq[char]? ", "throws err when adding subtype seq[char]" -echo "somevar isnot string? ", somevar isnot string - - -type MyType = ref object of RootObj -var instance: MyType = MyType() - -echo "is instance of MyType ", instance of MyType - echo "############################ echo and related" echo "just a regular echo statement" diff --git a/src/bookofnim/opensource/README.md b/src/bookofnim/opensource/README.md index 5e680e89..d0e1c730 100644 --- a/src/bookofnim/opensource/README.md +++ b/src/bookofnim/opensource/README.md @@ -17,6 +17,7 @@ - [arraymancer: deep learning tensor library](https://github.com/mratsim/Arraymancer) - [async tools: async utilities for nim](https://github.com/cheatfate/asynctools) - [Basolato: fullstack web framework](https://github.com/itsumura-h/nim-basolato) +- [bro: stylesheet language; aka the sass kiler](https://github.com/openpeeps/bro) - [c2nim: converts C and C++ header files to nim code](https://github.com/nim-lang/c2nim) - [docopt: create cli interfaces](https://github.com/docopt/docopt.nim) - [dsl: svg|gif generator](https://github.com/bluenote10/NimSvg) @@ -32,6 +33,7 @@ - [limbdb: kv store using lmdb](https://forum.nim-lang.org/t/9210) - [llvm based compiler for nim](https://github.com/arnetheduck/nlvm) - [macr-based pattern matching library](https://github.com/alehander92/gara) +- [malebolgia: spawn for embedded devices](https://github.com/Araq/malebolgia) - [moe: vim like editor that didnt work on the first try](https://github.com/fox0430/moe) - [mummy: http/websocket server](https://github.com/guzba/mummy) - [neel: create lightweight electron apps](https://github.com/Niminem/Neel) @@ -45,11 +47,13 @@ - [nimdata: data manipulation](https://github.com/bluenote10/NimData) - [nimib: convert your nim code and its outputs to html docs](https://github.com/pietroppeter/nimib) - [nimibook: port of mdbook to Nim](https://github.com/pietroppeter/nimibook) +- [nimpy: integration with python](https://github.com/yglukhov/nimpy) - [nimqt: bindings for QT interface development](https://github.com/jerous86/nimqt) - [nimquery: document.qerySelector+all for nim](https://github.com/GULPF/nimquery) - [nimtemplate: nim project/library starter kit](https://github.com/treeform/nimtemplate) - [NimTemplate: third-person template for unreal engine](https://github.com/jmgomez/NimTemplate) - [nimterlingua: compiletime i18](https://github.com/juancarlospaco/nim-nimterlingua) +- [nimuring: pure implementation of io_uring](https://github.com/blackmius/nimuring) - [nimx: cross platform GUI framework](https://github.com/yglukhov/nimx) - [NimYAML: serialize & stream yaml bidrectionally](https://github.com/flyx/NimYAML) - [nitch: neofetch alternative](https://github.com/unxsh/nitch) @@ -62,18 +66,21 @@ - [parlexgen: macro for generating lexers and parsers](https://github.com/choltreppe/parlexgen) - [presto: rest api from status-im built on chronos](https://github.com/status-im/nim-presto) - [prologue: web framework](https://github.com/planety/prologue) -- [prologue: web framework](https://github.com/planety/Prologue) - [qrgen: generate QR codes](https://github.com/aruZeta/QRgen) - [ready: redis client](https://github.com/guzba/ready) - [scorper: micro webframework built on chronos](https://github.com/bung87/scorper) +- [serverless-nim](https://github.com/epiphone/serverless-nim) +- [stash table: concurrent hash table](https://github.com/olliNiinivaara/StashTable) +- [sunk: then, catch and finally for futures](https://github.com/archnim/sunk) - [threadproxy: inter-thread communication](https://github.com/jackhftang/threadproxy.nim) - [ttop: sys monitoring tool](https://github.com/inv2004/ttop) - [uing: updated fork of nim-lang/ui](https://github.com/neroist/uing) - [vaf: http fuzzer](https://github.com/d4rckh/vaf) - [valido: string validators & sanitizers](https://github.com/openpeep/valido) +- [valido: string validators and sanitizers](https://github.com/openpeeps/valido) - [zippy: deflate,zlib,gzip,tarballs,zip files management](https://github.com/guzba/zippy) -## orgs/people with nim open source +## orgs/people with high-quality open source nim packages - [araq](https://github.com/Araq) - [cblake](https://github.com/c-blake) @@ -83,6 +90,8 @@ - [iffy](https://github.com/iffy) - [jiro](https://github.com/jiro4989) - [juan](https://github.com/juancarlospaco) +- [mratsim](https://github.com/mratsim) +- [openpeeps](https://github.com/openpeeps) - [planety](https://github.com/planety) - [pmunch](https://github.com/PMunch) - [ringabout](https://github.com/ringabout) @@ -114,6 +123,12 @@ - [protobuff serialization and binding generators](https://github.com/PMunch/protobuf-nim) +### functional + +#### zero functional + +- [zero-cost chaining for functional abstractions](https://github.com/zero-functional/zero-functional) + ### tools #### INim @@ -121,10 +136,17 @@ - [repl nim](https://github.com/inim-repl/INim) - dude this is a fkn must have +### async / concurrency + #### chronos - [asyncdispatch alternative used by some other popular pkgs](https://github.com/status-im/nim-chronos) -- [read this as well](https://nim-lang.org/docs/asyncdispatch.html#multiple-async-backend-support) +- [read this as well](https://nim-lang.github.io/Nim/asyncdispatch.html#multiple-async-backend-support) + +#### weave + +- [state-of-the-art multithreading runtime](https://github.com/mratsim/weave) +- std/channels is based on this project ### appdev @@ -144,6 +166,10 @@ - [graphql services in nim](https://github.com/status-im/nim-graphql) - supports http/s, sockets, i/rpc, stdin/out +#### denim + +- [native node/bun addons](https://github.com/openpeeps/denim) + ### starter kits #### nimtemplate diff --git a/src/bookofnim/opensource/channels.nim b/src/bookofnim/opensource/channels.nim new file mode 100644 index 00000000..f83b6124 --- /dev/null +++ b/src/bookofnim/opensource/channels.nim @@ -0,0 +1,91 @@ +# blah doesnt work +# ^ @see https://github.com/nim-lang/threading/pull/31 + +##[ +## TLDR +- its useful to think about threads and channels using the actor model + - actor: a procedure recreated on a thread to execute some logic + - its simpler for actors to pull/push data via a channel to/from other actors + - else you can pass data between actors through a thread when its created + - an actor can create additional actors/threads/channels + - channel: the bus in which data is sent between actors + - channels defined on the main/current thread are available to all sibling actors + - channels not defined on the main thread must be passed to other threads by ptr via an actor + - thread: where execution occurs on a CPU, 12-core machine has 12 concurrent execution contexts + - only a single thread can execute at any given time per cpu, timesharing occurs otherwise + - Thread[void]: no data is passed via thread to its actor; the actor uses a channel only + - Thread[NotVoid]: on thread creation, instance of NotVoid is expected and passed to its actor + - in order to pass multiple params, use something like a tuple/array/etc + + +## channels +- designed for system.threads, unstable when used with spawn +- deeply copies non cyclic data from thread X to thread Y +- channels declared in the main thread (module scope) is simpler and shared across all threads + - else you can declare within the body of proc thread and send the ptr to another + +channels types +-------------------- +- Channel[T] for relaying messages of type T + +channels procs +-------------------- +- close permenantly a channel and frees its resources +- open or update a channel with size int (0 == unlimited) +- peek at total messages in channel, -1 if channel closed, use tryRecv instead to avoid race conds +- ready true if some thread is waiting for new messages +- recv data; blocks its channel scope until delivered +- send deeply copied data; blocks its channel scope until sent +- tryRecv (bool, msg) +- trySend deeply copied data without blocking + + +]## +import std/assertions +import threading/channels + + +echo "############################ channelss" + +var + relay: Channel[string] ## a queue for string data + +echo "############################ channelss: blocking" + +proc sendAction: void {.thread.} = + sleep 500 + ## action for sending data + ## blocks its channel's scope until msg delivered; deep copies its arguments + relay.send "phone ring ring ring" + +proc receiveAction: void {.thread.} = + ## action for consuming data + ## recv blocks its channel's scope until msg received + echo fmt"blocking; busy binging mr.robot: {relay.recv()=}" + echo "unblocked: until i receive data" + +open relay, maxItems = 0 ## 0 = unlimited queue + +gf.createThread sendAction +bf.createThread receiveAction +joinThreads gf, bf + +echo "############################ channels: non blocking" + +proc sendActionA: void {.thread.} = + ## action for sending data without blocking + sleep 500 + ## deep copies its arguments + if not relay.trySend "phone ring ring ring": echo "failed to send message" + +proc receiveActionA: void {.thread.} = + ## action for consuming data without blocking + while true: + let comms = relay.tryRecv() + if comms.dataAvailable: echo fmt"non blocking: {comms.msg=}"; break + echo "never blocked: no data!" + sleep 400 ## before next check + +gf.createThread sendActionA +bf.createThread receiveActionA +joinThreads gf, bf diff --git a/src/bookofnim/opensource/dbs.nim b/src/bookofnim/opensource/dbs/dbs.nim similarity index 54% rename from src/bookofnim/opensource/dbs.nim rename to src/bookofnim/opensource/dbs/dbs.nim index 9193edc7..262d119e 100644 --- a/src/bookofnim/opensource/dbs.nim +++ b/src/bookofnim/opensource/dbs/dbs.nim @@ -15,22 +15,22 @@ links ----- - other - - [avoiding sql injections](https://nim-lang.org/docs/manual.html#distinct-type-avoiding-sql-injection-attacks) + - [avoiding sql injections](https://nim-lang.github.io/Nim/manual.html#distinct-type-avoiding-sql-injection-attacks) - [limbdb forum post](https://forum.nim-lang.org/t/9210) - [cloudflare lmbd post](https://blog.cloudflare.com/introducing-quicksilver-configuration-distribution-at-internet-scale/) - high impact - - [mysql client](https://nim-lang.org/docs/db_mysql.html) - - [postgres client](https://nim-lang.org/docs/db_postgres.html) - - [sqlite client](https://nim-lang.org/docs/db_sqlite.html) - - [generic odbc wrapper](https://nim-lang.org/docs/db_odbc.html) - - [sql parser](https://nim-lang.org/docs/parsesql.html) - - [mime types db for files & http servers](https://nim-lang.org/docs/mimetypes.html) + - [mysql client](https://nim-lang.github.io/Nim/db_mysql.html) + - [postgres client](https://nim-lang.github.io/Nim/db_postgres.html) + - [sqlite client](https://nim-lang.github.io/Nim/db_sqlite.html) + - [generic odbc wrapper](https://nim-lang.github.io/Nim/db_odbc.html) + - [sql parser](https://nim-lang.github.io/Nim/parsesql.html) + - [mime types db for files & http servers](https://nim-lang.github.io/Nim/mimetypes.html) - niche - - [postgres interface](https://nim-lang.org/docs/postgres.html) - - [sqlite interface](https://nim-lang.org/docs/sqlite3.html) - - [mysql interface](https://nim-lang.org/docs/mysql.html) - - [odbc interface](https://nim-lang.org/docs/odbcsql.html) - - [variable length ints](https://nim-lang.org/docs/varints.html) + - [postgres interface](https://nim-lang.github.io/Nim/postgres.html) + - [sqlite interface](https://nim-lang.github.io/Nim/sqlite3.html) + - [mysql interface](https://nim-lang.github.io/Nim/mysql.html) + - [odbc interface](https://nim-lang.github.io/Nim/odbcsql.html) + - [variable length ints](https://nim-lang.github.io/Nim/varints.html) ## sqlite, postgres & mysql - the interface should be the same between all 3 diff --git a/src/bookofnim/opensource/dbs/limbdb.nim b/src/bookofnim/opensource/dbs/limbdb.nim new file mode 100644 index 00000000..dd8f95bc --- /dev/null +++ b/src/bookofnim/opensource/dbs/limbdb.nim @@ -0,0 +1,3 @@ +##[ +- [0.3.0 release](https://forum.nim-lang.org/t/10193) +]## diff --git a/src/bookofnim/opensource/opensource.nim b/src/bookofnim/opensource/opensource.nim index b2eaacfc..8cb23136 100644 --- a/src/bookofnim/opensource/opensource.nim +++ b/src/bookofnim/opensource/opensource.nim @@ -3,7 +3,10 @@ ##[ ## TLDR -- comvert README.md to rst and include it in this file +- TODO(noah): comvert README.md to rst and include it in this file + - ^ thats a dumb idea, they should be segmented by category for testing purposes + - the main idea is to get a quick comparison of the API for competing packages + - focus on web servers as thats the part nim plays in nirv ]## diff --git a/src/bookofnim/v2/asyncParV2.nim b/src/bookofnim/v2/asyncParV2.nim deleted file mode 100644 index 6f333522..00000000 --- a/src/bookofnim/v2/asyncParV2.nim +++ /dev/null @@ -1,42 +0,0 @@ -## -## concurrency and parallelism (V2) -## ================================ - - -##[ -## TLDR -- changes in v2 - - system.thread types moved to std/private/threadtypes - - system.thread logic upgraded and moved to std/typedthreads - - system.threads still works in v2, but you should prefer std/typedthreads - -links ------ -- [std/typedthreads](https://github.com/nim-lang/Nim/blob/devel/lib/std/typedthreads.nim) -- [sys atomics](https://github.com/nim-lang/Nim/blob/devel/lib/std/sysatomics.nim) -- [system threadids](https://github.com/nim-lang/Nim/blob/devel/lib/system/threadids.nim) -- [system threadimpl](https://github.com/nim-lang/Nim/blob/devel/lib/system/threadimpl.nim) - -TODOs ------ -- see github issue, we should isolate all v2 async/par stuff in here - -## threads - -typedthreads procs ------------------- -- running true if thread is executing -- handle of thread -- joinThreads back to main thread -- joinThread back to main thread -- destroyThread is a potentially dangerous action -- createThread and start execution -- pinThread to a cpu & set its affinity - -]## - -{.push warning[UnusedImport]:off .} - -import std/typedthreads - -echo "asyncpar v2!" diff --git a/src/bookofnim/v2/cryptoV2.nim b/src/bookofnim/v2/cryptoV2.nim deleted file mode 100644 index 01baf8a3..00000000 --- a/src/bookofnim/v2/cryptoV2.nim +++ /dev/null @@ -1,17 +0,0 @@ -## -## crypto (V2) -## =========== - - -##[ -## TLDR -- changes in v2 - - -links ------ -]## - -{.push warning[UnusedImport]:off .} - -echo "dbs v2!" diff --git a/src/bookofnim/v2/dbsV2.nim b/src/bookofnim/v2/dbsV2.nim index 61083c41..b17d9b15 100644 --- a/src/bookofnim/v2/dbsV2.nim +++ b/src/bookofnim/v2/dbsV2.nim @@ -7,7 +7,7 @@ ## TLDR - changes in v2 - [std/lib db wrappers moved to nimble packages](https://github.com/nim-lang/Nim/commit/9ba07edb2ec7fcdd628cfa7155c4853160ebd5c3#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3) - + - [db_connector: sqlite](https://nim-lang.github.io/Nim/db_sqlite.html) links ----- ]## diff --git a/src/bookofnim/v2/nimv2.nim b/src/bookofnim/v2/nimv2.nim index 8f1b5fb6..263dc0ef 100644 --- a/src/bookofnim/v2/nimv2.nim +++ b/src/bookofnim/v2/nimv2.nim @@ -5,6 +5,7 @@ ##[ ## TLDR - migrating to V2 + - [read this article](https://nim-lang.org/blog/2022/12/21/version-20-rc.html) - [read this changelog](https://github.com/nim-lang/Nim/blob/9ba07edb2ec7fcdd628cfa7155c4853160ebd5c3/changelog.md) - system modules moved to std library - assertions > std/assertions @@ -44,7 +45,7 @@ TODOs - [nimtracker](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/pure/nimtracker.nim) - [punycode](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/pure/punycode.nim) - [smtp](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/pure/smtp.nim) -- think the db stuff were just moved somewhere else +- are now nimble packages - [mysql](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/wrappers/mysql.nim) - [odbcsql](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/wrappers/odbcsql.nim) - [postgres](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/wrappers/postgres.nim) @@ -60,6 +61,26 @@ TODOs - [threads](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/system/threads.nim) - [widestrs](https://github.com/nim-lang/Nim/blob/v1.6.12/lib/system/widestrs.nim) + system modules now std modules + std/syncio + std/assertions + std/formatfloat + std/objectdollar + std/widestrs + std/typedthreads + std/sysatomics + + std modules now nimble packages + std/punycode => punycode + std/asyncftpclient => asyncftpclient + std/smtp => smtp + std/db_common => db_connector/db_common + std/db_sqlite => db_connector/db_sqlite + std/db_mysql => db_connector/db_mysql + std/db_postgres => db_connector/db_postgres + std/db_odbc => db_connector/db_odbc + + ]## {.push warning[UnusedImport]:off .} diff --git a/src/bookofnim/v2/serversV2.nim b/src/bookofnim/v2/serversV2.nim deleted file mode 100644 index e69de29b..00000000 diff --git a/src/nimnotes.md b/src/nimnotes.md index ce855891..7c584edc 100644 --- a/src/nimnotes.md +++ b/src/nimnotes.md @@ -31,25 +31,25 @@ - [fuzz tests](https://github.com/status-im/nim-testutils/tree/master/testutils/fuzzing) - tuts - [bunches of tuts](https://nim-lang.org/documentation.html) - - [nim tutorial](https://nim-lang.org/docs/tut1.html) + - [nim tutorial](https://nim-lang.github.io/Nim/tut1.html) - [nim for typescript programmers tutorial](https://github.com/nim-lang/Nim/wiki/Nim-for-TypeScript-Programmers) - [nim by example](https://nim-by-example.github.io/getting_started/) - - [nim style guide](https://nim-lang.org/docs/nep1.html) + - [nim style guide](https://nim-lang.github.io/Nim/nep1.html) - specs - - [nim manual](https://nim-lang.org/docs/manual.html) - - [sugar](https://nim-lang.org/docs/sugar.html) - - [assertions](https://nim-lang.org/docs/assertions.html) + - [nim manual](https://nim-lang.github.io/Nim/manual.html) + - [sugar](https://nim-lang.github.io/Nim/sugar.html) + - [assertions](https://nim-lang.github.io/Nim/assertions.html) - [quick intro](https://narimiran.github.io/nim-basics/) - - [compiler user guide](https://nim-lang.org/docs/nimc.html) - - [docgen tools guide](https://nim-lang.org/docs/docgen.html) - - [docs](https://nim-lang.org/docs/lib.html) + - [compiler user guide](https://nim-lang.github.io/Nim/nimc.html) + - [docgen tools guide](https://nim-lang.github.io/Nim/docgen.html) + - [docs](https://nim-lang.github.io/Nim/lib.html) - specs - - [manual](https://nim-lang.org/docs/manual.html) - - [experimental features](https://nim-lang.org/docs/manual_experimental.html) - - [nim destructors and move semantics](https://nim-lang.org/docs/destructors.html) - - [standard library](https://nim-lang.org/docs/lib.html) + - [manual](https://nim-lang.github.io/Nim/manual.html) + - [experimental features](https://nim-lang.github.io/Nim/manual_experimental.html) + - [nim destructors and move semantics](https://nim-lang.github.io/Nim/destructors.html) + - [standard library](https://nim-lang.github.io/Nim/lib.html) - [nim for flow programmers](https://github.com/nim-lang/Nim/wiki/Nim-for-TypeScript-Programmers) - - [cmdline](https://nim-lang.org/docs/nimc.html) + - [cmdline](https://nim-lang.github.io/Nim/nimc.html) ## basics @@ -59,6 +59,8 @@ ### terms +- compile time function evaluation: CTFE +- dependency tracking - autovivification: creating tree structures on the fly - locations: something im memory consisting of some type of component; a variable is a name for a location - each variable and location is of a certain type diff --git a/testresults.html b/testresults.html new file mode 100644 index 00000000..035f507f --- /dev/null +++ b/testresults.html @@ -0,0 +1,485 @@ + + + + + Testament Test Results + + + + + + + +
+

Testament Test Results Nim Tester

+
+
Hostname
+
spaceship
+
Git Commit
+
273bfecc724
+
Branch ref.
+
nimv2
+
+
+
All Tests
+
+ + 9 +
+
Successful Tests
+
+ + 7 (77.78%) +
+
Skipped Tests
+
+ + 2 (22.22%) +
+
Failed Tests
+
+ + 0 (0.00%) +
+
+
+ + + + + + + + + + + + + + + + + +
All Tests +
+ + + + +
+
Successful Tests +
+ + + + +
+
Skipped Tests +
+ + + + +
+
Failed Tests +
+ + + + +
+
+
+
+
+ +
+
+
Name
+
tests/backends/tc.nim c
+
Category
+
backends
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reSuccess
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/backends/tcpp.nim c
+
Category
+
backends
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reSuccess
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/backends/tnodeBrowser.nim c
+
Category
+
backends
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reSuccess
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/backends/tobjc.nim c
+
Category
+
backends
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reSuccess
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/deepdives/tdeepdives.nim c
+
Category
+
deepdives
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reSuccess
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/deepdives/tmemoryLeaks.nim c
+
Category
+
deepdives
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reDisabled
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/helloworld/thelloworld.nim c
+
Category
+
helloworld
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reSuccess
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/opensource/tdbs.nim c
+
Category
+
opensource
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reSuccess
+
+

No output details

+
+
+
+ +
+
+
Name
+
tests/targets/tshell.nim c
+
Category
+
targets
+
Timestamp
+
unknown
+
Nim Action
+
run
+
Nim Backend Target
+
c
+
Code
+
reDisabled
+
+

No output details

+
+
+
+
+ +
+ + diff --git a/tests/config.nims b/tests/config.nims index ae7712f1..28997638 100644 --- a/tests/config.nims +++ b/tests/config.nims @@ -21,8 +21,18 @@ when defined(windows): # internal switch("assertions", "on") +switch("debuginfo", "on") +switch("declaredLocs", "on") +switch("excessiveStackTrace", "on") +switch("forceBuild", "on") switch("path", "$projectDir/../../src") # relative to test files switch("putenv", "NIM_TESTAMENT_REMOTE_NETWORKING=1") -switch("putenv", "TEST=1") # dont set ENV=TEST; this enables us to run tests against any env +switch("putenv", "TEST=1") switch("stackTraceMsgs", "on") switch("verbosity", "2") + +case existsEnv "DEV": + of false: + --forceBuild:on + --parallelBuild:1 + else: discard diff --git a/tests/deepdives/tdeepdives.nim b/tests/deepdives/tdeepdives.nim index 0e291534..9da46e07 100644 --- a/tests/deepdives/tdeepdives.nim +++ b/tests/deepdives/tdeepdives.nim @@ -3,6 +3,7 @@ discard """ valgrind: true """ +# TODO(noah): we broke this apart because theres some memory leaks in certain files import bookofnim / deepdives / [ collections, ## non list/queues, e.g. arrays and seqs containers, ## tuples, tables and object diff --git a/todo_skipped.nim b/todo_skipped.nim index 63db1290..8d946e56 100644 --- a/todo_skipped.nim +++ b/todo_skipped.nim @@ -9,6 +9,8 @@ - [figure out what genode is](https://genode.org/) - [nim has a dir dedicated to genode](https://github.com/nim-lang/Nim/tree/devel/lib/genode) - [and another](https://github.com/nim-lang/Nim/tree/devel/lib/genode_cpp) +- [atlas shrugged](https://forum.nim-lang.org/t/10234) + - [tut](https://github.com/nim-lang/atlas/blob/master/readme.md) ## new list of TODOs - async / para stuff