trackler 2.2.1.138 → 2.2.1.139
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/crypto-square/description.md +23 -19
- data/problem-specifications/exercises/yacht/canonical-data.json +10 -1
- data/tracks/clojure/exercises/gigasecond/src/gigasecond.clj +5 -0
- data/tracks/clojure/exercises/grade-school/src/grade_school.clj +13 -0
- data/tracks/clojure/exercises/grains/src/grains.clj +9 -0
- data/tracks/clojure/exercises/minesweeper/src/minesweeper.clj +5 -0
- data/tracks/fsharp/docs/GENERATORS.md +12 -14
- data/tracks/fsharp/exercises/bowling/BowlingTest.fs +15 -15
- data/tracks/fsharp/exercises/perfect-numbers/PerfectNumbersTest.fs +11 -11
- data/tracks/fsharp/exercises/rna-transcription/Example.fs +7 -15
- data/tracks/fsharp/exercises/rna-transcription/RnaTranscription.fs +1 -1
- data/tracks/fsharp/exercises/rna-transcription/RnaTranscriptionTest.fs +5 -5
- data/tracks/fsharp/exercises/robot-simulator/RobotSimulatorTest.fs +34 -34
- data/tracks/fsharp/exercises/sublist/Example.fs +1 -1
- data/tracks/fsharp/exercises/sublist/Sublist.fs +1 -1
- data/tracks/fsharp/exercises/sublist/SublistTest.fs +17 -17
- data/tracks/fsharp/exercises/word-search/WordSearchTest.fs +56 -57
- data/tracks/fsharp/generators/CanonicalData.fs +14 -15
- data/tracks/fsharp/generators/Common.fs +4 -84
- data/tracks/fsharp/generators/Conversion.fs +75 -0
- data/tracks/fsharp/generators/Exercise.fs +15 -11
- data/tracks/fsharp/generators/Generators.fs +294 -468
- data/tracks/fsharp/generators/Generators.fsproj +2 -1
- data/tracks/fsharp/generators/Rendering.fs +169 -61
- data/tracks/fsharp/generators/Templates.fs +64 -0
- data/tracks/fsharp/generators/Track.fs +3 -3
- data/tracks/idris/exercises/accumulate/src/Example.idr +1 -1
- data/tracks/idris/exercises/accumulate/src/Test/Accumulate.idr +2 -2
- data/tracks/java/exercises/rna-transcription/.meta/hints.md +2 -0
- data/tracks/java/exercises/rna-transcription/README.md +6 -0
- data/tracks/nim/.gitignore +1 -0
- data/tracks/nim/config.json +38 -0
- data/tracks/nim/config/maintainers.json +10 -0
- data/tracks/nim/docs/ABOUT.md +7 -0
- data/tracks/nim/exercises/bob/README.md +2 -0
- data/tracks/nim/exercises/bob/bob_test.nim +31 -13
- data/tracks/nim/exercises/bob/example.nim +2 -2
- data/tracks/nim/exercises/gigasecond/README.md +22 -0
- data/tracks/nim/exercises/gigasecond/example.nim +4 -0
- data/tracks/nim/exercises/gigasecond/gigasecond_test.nim +32 -0
- data/tracks/nim/exercises/isogram/README.md +20 -0
- data/tracks/nim/exercises/isogram/example.nim +6 -0
- data/tracks/nim/exercises/isogram/isogram_test.nim +32 -0
- data/tracks/nim/exercises/space-age/README.md +24 -0
- data/tracks/nim/exercises/space-age/example.nim +17 -0
- data/tracks/nim/exercises/space-age/space_age_test.nim +29 -0
- data/tracks/nim/exercises/triangle/example.nim +22 -22
- data/tracks/nim/exercises/triangle/triangle_test.nim +32 -44
- metadata +19 -3
- data/tracks/fsharp/generators/Formatting.fs +0 -189
@@ -7,11 +7,12 @@
|
|
7
7
|
|
8
8
|
<ItemGroup>
|
9
9
|
<Compile Include="Common.fs" />
|
10
|
+
<Compile Include="Conversion.fs" />
|
10
11
|
<Compile Include="Options.fs" />
|
11
12
|
<Compile Include="CanonicalData.fs" />
|
12
13
|
<Compile Include="Track.fs" />
|
13
|
-
<Compile Include="Formatting.fs" />
|
14
14
|
<Compile Include="Rendering.fs" />
|
15
|
+
<Compile Include="Templates.fs" />
|
15
16
|
<Compile Include="Exercise.fs" />
|
16
17
|
<Compile Include="Generators.fs" />
|
17
18
|
<Compile Include="Program.fs" />
|
@@ -1,64 +1,172 @@
|
|
1
1
|
module Generators.Rendering
|
2
2
|
|
3
|
-
open System
|
4
|
-
open System.Collections.Generic
|
5
|
-
open System.Reflection
|
3
|
+
open System
|
6
4
|
open FSharp.Reflection
|
7
|
-
open
|
8
|
-
open
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
if
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
let
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
5
|
+
open Newtonsoft.Json.Linq
|
6
|
+
open Conversion
|
7
|
+
|
8
|
+
module String =
|
9
|
+
|
10
|
+
let private escapeSpecialCharacters(str: string) =
|
11
|
+
str.Replace("\n", "\\n")
|
12
|
+
.Replace("\t", "\\t")
|
13
|
+
.Replace("\r", "\\r")
|
14
|
+
.Replace("\"", "\\\"")
|
15
|
+
|
16
|
+
let render (str: string) =
|
17
|
+
str
|
18
|
+
|> escapeSpecialCharacters
|
19
|
+
|> String.enquote
|
20
|
+
|
21
|
+
module Bool =
|
22
|
+
|
23
|
+
let render b = if b then "true" else "false"
|
24
|
+
|
25
|
+
module DateTime =
|
26
|
+
|
27
|
+
let render (dateTime: DateTime) =
|
28
|
+
if dateTime.TimeOfDay = TimeSpan.Zero then
|
29
|
+
sprintf "DateTime(%d, %d, %d)" dateTime.Year dateTime.Month dateTime.Day
|
30
|
+
else
|
31
|
+
sprintf "DateTime(%d, %d, %d, %d, %d, %d)" dateTime.Year dateTime.Month dateTime.Day dateTime.Hour dateTime.Minute dateTime.Second
|
32
|
+
|
33
|
+
let renderParenthesized (dateTime: DateTime) =
|
34
|
+
dateTime
|
35
|
+
|> render
|
36
|
+
|> String.parenthesize
|
37
|
+
|
38
|
+
module Obj =
|
39
|
+
|
40
|
+
let private renderJToken (jToken: JToken) =
|
41
|
+
match jToken.Type with
|
42
|
+
| JTokenType.Integer -> jToken.ToObject<int64>() |> string
|
43
|
+
| JTokenType.Float -> jToken.ToObject<float>() |> string
|
44
|
+
| JTokenType.Boolean -> jToken.ToObject<bool>() |> Bool.render
|
45
|
+
| JTokenType.String -> jToken.ToObject<string>() |> String.render
|
46
|
+
| JTokenType.Date -> jToken.ToObject<DateTime>() |> DateTime.render
|
47
|
+
| _ -> string jToken
|
48
|
+
|
49
|
+
let private renderTuple tuple = sprintf "%A" tuple
|
50
|
+
|
51
|
+
let private renderRecord record = sprintf "%A" record
|
52
|
+
|
53
|
+
let rec private renderObj (value: obj) =
|
54
|
+
let rec renderJArray (jArray: JArray) =
|
55
|
+
jArray
|
56
|
+
|> Seq.map renderObj
|
57
|
+
|> String.concat "; "
|
58
|
+
|> sprintf "[%s]"
|
59
|
+
|
60
|
+
match value with
|
61
|
+
| :? string as s ->
|
62
|
+
String.render s
|
63
|
+
| :? bool as b ->
|
64
|
+
Bool.render b
|
65
|
+
| :? DateTime as dateTime ->
|
66
|
+
DateTime.render dateTime
|
67
|
+
| :? JArray as jArray ->
|
68
|
+
renderJArray jArray
|
69
|
+
| :? JToken as jToken ->
|
70
|
+
renderJToken jToken
|
71
|
+
| _ when FSharpType.IsTuple (value.GetType()) ->
|
72
|
+
renderTuple value
|
73
|
+
| _ when FSharpType.IsRecord (value.GetType()) ->
|
74
|
+
renderRecord value
|
75
|
+
| _ ->
|
76
|
+
string value
|
77
|
+
|
78
|
+
let render value = renderObj value
|
79
|
+
|
80
|
+
let renderEnum typeName value =
|
81
|
+
let enumType = String.upperCaseFirst typeName
|
82
|
+
let enumValue = String.dehumanize (string value)
|
83
|
+
sprintf "%s.%s" enumType enumValue
|
84
|
+
|
85
|
+
module Option =
|
86
|
+
|
87
|
+
let private renderMap valueMap someMap option =
|
88
|
+
match option with
|
89
|
+
| None -> "None"
|
90
|
+
| Some value -> sprintf "Some %s" (valueMap value) |> someMap
|
91
|
+
|
92
|
+
let renderString option = renderMap id id option
|
93
|
+
|
94
|
+
let renderStringParenthesized option = renderMap id String.parenthesize option
|
95
|
+
|
96
|
+
let render option = renderMap Obj.render id option
|
97
|
+
|
98
|
+
let renderParenthesized option = renderMap Obj.render String.parenthesize option
|
99
|
+
|
100
|
+
module Collection =
|
101
|
+
let render formatString collection =
|
102
|
+
collection
|
103
|
+
|> String.concat "; "
|
104
|
+
|> sprintf formatString
|
105
|
+
|
106
|
+
let renderMultiLine openPrefix closePostfix collection =
|
107
|
+
match Seq.length collection with
|
108
|
+
| 0 ->
|
109
|
+
sprintf "%s%s" openPrefix closePostfix
|
110
|
+
| 1 ->
|
111
|
+
sprintf "%s%s%s" openPrefix (Seq.head collection) closePostfix
|
112
|
+
| length ->
|
113
|
+
let lineIndent = String(' ', String.length openPrefix)
|
114
|
+
|
115
|
+
let formatLine i line =
|
116
|
+
match i with
|
117
|
+
| 0 ->
|
118
|
+
sprintf "%s %s;" openPrefix line
|
119
|
+
| _ when i = length - 1 ->
|
120
|
+
sprintf "%s %s %s" lineIndent line closePostfix
|
121
|
+
| _ ->
|
122
|
+
sprintf "%s %s;" lineIndent line
|
123
|
+
|
124
|
+
collection
|
125
|
+
|> Seq.mapi formatLine
|
126
|
+
|> Seq.toList
|
127
|
+
|> List.map (String.indent 2)
|
128
|
+
|> String.concat "\n"
|
129
|
+
|> sprintf "\n%s"
|
130
|
+
|
131
|
+
module List =
|
132
|
+
|
133
|
+
let mapRender map value = Collection.render "[%s]" (Seq.map map value)
|
134
|
+
|
135
|
+
let mapRenderMultiLine map value = Collection.renderMultiLine "[" "]" (Seq.map map value)
|
136
|
+
|
137
|
+
let render value = mapRender Obj.render value
|
138
|
+
|
139
|
+
let renderMultiLine value = mapRenderMultiLine Obj.render value
|
140
|
+
|
141
|
+
module Array =
|
142
|
+
|
143
|
+
let renderStrings value = Collection.render "[|%s|]" value
|
144
|
+
|
145
|
+
let render value =
|
146
|
+
value
|
147
|
+
|> Seq.map Obj.render
|
148
|
+
|> renderStrings
|
149
|
+
|
150
|
+
module Map =
|
151
|
+
|
152
|
+
let private renderMap<'TKey, 'TValue> map suffix (value: JToken) =
|
153
|
+
let dict = value.ToObject<Collections.Generic.Dictionary<'TKey, 'TValue>>()
|
154
|
+
let formattedList = List.mapRenderMultiLine map dict
|
155
|
+
let whitespace = if Seq.length dict < 2 then " " else sprintf "\n%s" (String.indent 2 "")
|
156
|
+
sprintf "%s%s|> Map.ofList%s" formattedList whitespace suffix
|
157
|
+
|
158
|
+
let mapRender<'TKey, 'TValue> map (value: JToken) =
|
159
|
+
renderMap<'TKey, 'TValue> map "" value
|
160
|
+
|
161
|
+
let render<'TKey, 'TValue> (value: JToken) =
|
162
|
+
mapRender<'TKey, 'TValue> (fun kv -> Obj.render(kv.Key, kv.Value)) value
|
163
|
+
|
164
|
+
let mapRenderOption<'TKey, 'TValue> map (option: JToken option) =
|
165
|
+
match option with
|
166
|
+
| None -> "None"
|
167
|
+
| Some value ->
|
168
|
+
let suffix = if Seq.length value < 2 then " |> Some" else sprintf "\n%s" (String.indent 2 "|> Some")
|
169
|
+
renderMap<'TKey, 'TValue> map suffix value
|
170
|
+
|
171
|
+
let renderOption<'TKey, 'TValue> (option: JToken option) =
|
172
|
+
mapRenderOption<'TKey, 'TValue> (fun kv -> Obj.render(kv.Key, kv.Value)) option
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Generators.Templates
|
2
|
+
|
3
|
+
open System.IO
|
4
|
+
open System.Collections.Generic
|
5
|
+
open System.Reflection
|
6
|
+
open FSharp.Reflection
|
7
|
+
open DotLiquid
|
8
|
+
open DotLiquid.FileSystems
|
9
|
+
open Rendering
|
10
|
+
|
11
|
+
type OutputFilter() =
|
12
|
+
static member Format (input: string) = Obj.render input
|
13
|
+
|
14
|
+
static member Indent (input: string) = String.indent 1 input
|
15
|
+
|
16
|
+
let private fileSystem = LocalFileSystem(Path.GetFullPath("./Templates"))
|
17
|
+
Template.RegisterFilter(OutputFilter().GetType())
|
18
|
+
Template.FileSystem <- fileSystem :> DotLiquid.FileSystems.IFileSystem
|
19
|
+
|
20
|
+
let private registrations = Dictionary<_,_>()
|
21
|
+
let rec private registerTypeTree templateDataType =
|
22
|
+
if registrations.ContainsKey templateDataType then ()
|
23
|
+
elif FSharpType.IsRecord templateDataType then
|
24
|
+
let properties = templateDataType.GetProperties(BindingFlags.Instance ||| BindingFlags.Public)
|
25
|
+
Template.RegisterSafeType(templateDataType, [| for p in properties -> p.Name |])
|
26
|
+
registrations.[templateDataType] <- true
|
27
|
+
for p in properties do registerTypeTree p.PropertyType
|
28
|
+
elif templateDataType.IsGenericType then
|
29
|
+
let t = templateDataType.GetGenericTypeDefinition()
|
30
|
+
if t = typedefof<seq<_>> || t = typedefof<list<_>> then
|
31
|
+
registrations.[templateDataType] <- true
|
32
|
+
registerTypeTree (templateDataType.GetGenericArguments().[0])
|
33
|
+
elif t = typedefof<IDictionary<_,_>> || t = typedefof<Map<_,_>> then
|
34
|
+
registrations.[templateDataType] <- true
|
35
|
+
registerTypeTree (templateDataType.GetGenericArguments().[0])
|
36
|
+
registerTypeTree (templateDataType.GetGenericArguments().[1])
|
37
|
+
elif t = typedefof<option<_>> then
|
38
|
+
Template.RegisterSafeType(templateDataType, [|"Value"; "IsSome"; "IsNone";|])
|
39
|
+
registrations.[templateDataType] <- true
|
40
|
+
registerTypeTree (templateDataType.GetGenericArguments().[0])
|
41
|
+
elif templateDataType.IsArray then
|
42
|
+
registrations.[templateDataType] <- true
|
43
|
+
registerTypeTree (templateDataType.GetElementType())
|
44
|
+
else
|
45
|
+
let properties = templateDataType.GetProperties(BindingFlags.Instance ||| BindingFlags.Public)
|
46
|
+
Template.RegisterSafeType(templateDataType, [| for p in properties -> p.Name |])
|
47
|
+
registrations.[templateDataType] <- true
|
48
|
+
for p in properties do registerTypeTree p.PropertyType
|
49
|
+
|
50
|
+
let private hashFromData (data: obj) =
|
51
|
+
match FSharpType.IsRecord (data.GetType()) with
|
52
|
+
| true -> Hash.FromAnonymousObject(data)
|
53
|
+
| false -> Hash.FromDictionary(data :?> IDictionary<string, obj>)
|
54
|
+
|
55
|
+
let renderInlineTemplate template data =
|
56
|
+
data.GetType() |> registerTypeTree
|
57
|
+
|
58
|
+
let parsedTemplate = Template.Parse template
|
59
|
+
let hash = hashFromData data
|
60
|
+
parsedTemplate.Render(hash)
|
61
|
+
|
62
|
+
let renderPartialTemplate templateName data =
|
63
|
+
let template = sprintf "{%% include \"%s\" %%}" templateName
|
64
|
+
renderInlineTemplate template data
|
@@ -14,12 +14,12 @@ let private convertTrackConfig trackConfigContents = JsonConvert.DeserializeObje
|
|
14
14
|
|
15
15
|
let private trackConfigFile = Path.Combine("..", "config.json")
|
16
16
|
|
17
|
-
let private readTrackConfig = File.ReadAllText trackConfigFile
|
17
|
+
let private readTrackConfig() = File.ReadAllText trackConfigFile
|
18
18
|
|
19
|
-
let private parseTrackConfig = convertTrackConfig readTrackConfig
|
19
|
+
let private parseTrackConfig() = convertTrackConfig (readTrackConfig())
|
20
20
|
|
21
21
|
let isDeprecated =
|
22
|
-
let config = parseTrackConfig
|
22
|
+
let config = parseTrackConfig()
|
23
23
|
|
24
24
|
fun exercise ->
|
25
25
|
config.Exercises
|
@@ -8,7 +8,7 @@ assertEq : Eq a => String -> (given : a) -> (expected : a) -> IO ()
|
|
8
8
|
assertEq label g e = putStrLn $ if g == e then label ++ ": Test Passed" else label ++ ": Test Failed"
|
9
9
|
|
10
10
|
testEmptyListDoesNothing : IO ()
|
11
|
-
testEmptyListDoesNothing = assertEq "empty list does nothing" (accumulate (\x => x) []) []
|
11
|
+
testEmptyListDoesNothing = assertEq "empty list does nothing" (accumulate (\x => x) []) (the (List Int) [])
|
12
12
|
|
13
13
|
testIdentityFunctionDoesNothing : IO ()
|
14
14
|
testIdentityFunctionDoesNothing = assertEq "identity function does nothing" (accumulate (\x => x) [1,2,3]) [1,2,3]
|
@@ -23,7 +23,7 @@ testIncrementFunctionAddsOneToAllInput : IO ()
|
|
23
23
|
testIncrementFunctionAddsOneToAllInput = assertEq "increment function adds 1 to input" (accumulate (\x => x + 1) [1,2,3]) [2,3,4]
|
24
24
|
|
25
25
|
testDecrementFunctionAddsOneToAllInput : IO ()
|
26
|
-
testDecrementFunctionAddsOneToAllInput = assertEq "decrement function subtracts 1 from input" (accumulate (\x => x - 1) [1,2,3]) [0,1,2]
|
26
|
+
testDecrementFunctionAddsOneToAllInput = assertEq "decrement function subtracts 1 from input" (accumulate (\x => x - 1) [1,2,3]) (the (List Int) [0,1,2])
|
27
27
|
|
28
28
|
runTests : IO ()
|
29
29
|
runTests = do
|
@@ -18,6 +18,12 @@ each nucleotide with its complement:
|
|
18
18
|
* `T` -> `A`
|
19
19
|
* `A` -> `U`
|
20
20
|
|
21
|
+
# Java Tips
|
22
|
+
|
23
|
+
For more help on how to solve this exercise, please refer to the tutorial provided as part of the hello world exercise:
|
24
|
+
[TUTORIAL.md](https://github.com/exercism/java/blob/master/exercises/hello-world/TUTORIAL.md)
|
25
|
+
|
26
|
+
|
21
27
|
# Running the tests
|
22
28
|
|
23
29
|
You can run all the tests for an exercise by entering
|
data/tracks/nim/.gitignore
CHANGED
data/tracks/nim/config.json
CHANGED
@@ -171,6 +171,44 @@
|
|
171
171
|
"bitwise_operations",
|
172
172
|
"enumerations"
|
173
173
|
]
|
174
|
+
},
|
175
|
+
{
|
176
|
+
"uuid": "dccdbae7-e882-4171-a517-04562113d059",
|
177
|
+
"slug": "gigasecond",
|
178
|
+
"core": false,
|
179
|
+
"unlocked_by": null,
|
180
|
+
"difficulty": 1,
|
181
|
+
"topics": [
|
182
|
+
"dates",
|
183
|
+
"time"
|
184
|
+
]
|
185
|
+
},
|
186
|
+
{
|
187
|
+
"uuid": "64f70cfe-e34c-43ee-9b9a-72fe54884599",
|
188
|
+
"slug": "space-age",
|
189
|
+
"core": false,
|
190
|
+
"unlocked_by": null,
|
191
|
+
"difficulty": 1,
|
192
|
+
"topics": [
|
193
|
+
"mathematics",
|
194
|
+
"floating_point_numbers",
|
195
|
+
"integers",
|
196
|
+
"conditionals"
|
197
|
+
]
|
198
|
+
},
|
199
|
+
{
|
200
|
+
"uuid": "b1eb9f3c-8724-4b88-a545-2fe34b12b9cf",
|
201
|
+
"slug": "isogram",
|
202
|
+
"core": false,
|
203
|
+
"unlocked_by": null,
|
204
|
+
"difficulty": 1,
|
205
|
+
"topics": [
|
206
|
+
"conditionals",
|
207
|
+
"loops",
|
208
|
+
"strings",
|
209
|
+
"algorithms",
|
210
|
+
"maps"
|
211
|
+
]
|
174
212
|
}
|
175
213
|
]
|
176
214
|
}
|
@@ -9,6 +9,16 @@
|
|
9
9
|
"link_text": null,
|
10
10
|
"link_url": null,
|
11
11
|
"avatar_url": null
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"github_username": "amscotti",
|
15
|
+
"show_on_website": true,
|
16
|
+
"alumnus": false,
|
17
|
+
"name": "Anthony Scotti",
|
18
|
+
"bio": null,
|
19
|
+
"link_text": null,
|
20
|
+
"link_url": "https://128bit.io",
|
21
|
+
"avatar_url": null
|
12
22
|
}
|
13
23
|
],
|
14
24
|
"docs_url": "https://github.com/exercism/docs/blob/master/maintaining-a-track/maintainer-configuration.md"
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Nim is a general-purpose language designed and developed by Andreas Rumpf and first appearing in 2008. Designed to be efficient, expressive, and elegant. Nim is statically typed and compiled but lets you write elegant code that runs efficiently. Nim lets you target many platforms by compiling code to C, C++, JavaScript, or Objective-C. Nim syntax is similar to Python and shares many of Python's characteristics but draws inspiration from a number of languages, such as C, C++, C#, Lisp, Ada, Go, Oberon, and others.
|
2
|
+
|
3
|
+
As Nim is a general-purpose language it can be used in various places but has been filling a real niche in the area of Game development and Systems Programming including Embedded systems.
|
4
|
+
|
5
|
+
Nim gives you a lot of the convenience you find in Python and other languages, like easy to read syntax, a package management system for using new libraries in your projects, and user-friendly tracebacks for debugging errors.
|
6
|
+
|
7
|
+
Nim gives you the speed and portability of C, but with a high-performance garbage-collector and elegant syntax that makes the language very approachable to new people. Nim also gives you control, letting you change the garbage-collector or turn it off completely giving you the option to manage memory yourself. You have a variety of programming paradigms and abstraction layers with Nim.
|