This repository has been archived by the owner on Mar 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from Isible/rewrite
Rewrite
- Loading branch information
Showing
35 changed files
with
1,823 additions
and
2,922 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"key": "alt+s", | ||
"command": "editor.action.smartSelect.grow", | ||
"when": "editorTextFocus" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,10 @@ | ||
[package] | ||
name = "nexus" | ||
name = "nexus-lib" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
description = "A modern and simple scripting language" | ||
license = "MIT" | ||
repository = "https://github.com/MuffinGroup/nexus" | ||
readme = "README.md" | ||
|
||
authors = ["Thepigcat76 <benpospo@gmail.com>", "TheHackerChampion"] | ||
keywords = ["rust", "nexus", "scripting", "language"] | ||
homepage = "https://muffingroup.github.io/MuffinSite/" | ||
description = "The raw implementation of the nexus scripting language" | ||
|
||
[dependencies] | ||
clutils = "0.0.3" | ||
colored = "2.0.4" | ||
maplit = "1.0.2" | ||
clutils = "0.0.7" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
# Null handling | ||
|
||
## The Problem with null/none | ||
|
||
Null or None as it is called in some programming languages, bears a huge risk: Using a null-value where a non-null-value is expected, leading to errors, crashes or even undefined behaviour. | ||
|
||
However, not having a null/none type in many cases is as bad if not even worse than having one. Since the absense of this concept leads to people using others ways to display the absence of a value which due to not being handled as well as null can lead to the same bugs that are a lot harder to debug. | ||
|
||
And if you don't have any ideas, just take **inspiration** from other languages :p | ||
|
||
## Taking a look at other languages | ||
|
||
Let's look at other languages and how they handle intializing a nullable value | ||
|
||
### Kotlin | ||
|
||
Let's look at this kotlin code to see a very simple example of using null | ||
|
||
```kotlin | ||
fun main() { | ||
var test: String? = "Hello" | ||
test = null | ||
} | ||
``` | ||
|
||
As you might have realised there is a question mark behind the type annotation which indicates that we want the variable to be able to represent `null`. | ||
|
||
While this system is very intuitive, this is also one of its main flaws, sice you don't want null to be intuitive or people will use it without thinking about it twice, leading to the previously mentioned problems. | ||
|
||
So let's take a look at the next language, `rust`! | ||
|
||
### Rust | ||
|
||
```rust | ||
fn main() { | ||
let mut test: Option<&str> = Some("Hello"); | ||
test = None; | ||
} | ||
``` | ||
|
||
As you might have realized, this is a lot more code than the kotlin example. And if you also looked at the type you can spot that unlike the previous example this is not actually a direct string but a wrapper around it. | ||
|
||
While this is not as intuitive and simple as the kotlin example it also makes the user think twice if they actually want to/need to use null and also makes them aware of the potential null value beforehand. | ||
|
||
### Conclusion | ||
|
||
While I praised rust's implementation a lot, I think that in the context of a simple, interpreted, beginner-friendly language it does not make sense to use a complex system like that but rather take a closer look at kotlin. | ||
|
||
## Null references | ||
|
||
Before we actually take a look at how we ourselves can fix the issue, we also need to consider the other part of the puzzle: Referencing a value that potentially is a null value. | ||
|
||
### Kotlin | ||
|
||
While kotlin's solution looks a lot more distinct from rust, under the hood they basically work the same. You have a wrapper for the value and when you want to access it you have to consider that the value might be null. There are two effective ways to do so: | ||
|
||
#### 1. The safe approach | ||
|
||
We pass on the value to the next variable until we are ready to safely unwrap it | ||
|
||
```kotlin | ||
fun main() { | ||
var test: String? = null | ||
val firstChar: Char? = test?.get(0) | ||
// ^ this way we safely call the method | ||
if firstChar != null { | ||
// unwrap the value and do something with it | ||
} | ||
} | ||
``` | ||
|
||
#### 2. The unsafe approach | ||
|
||
We just unwrap the value regardless of whether it might be null or not and risk throwing an error. | ||
|
||
```kotlin | ||
fun main() { | ||
var test: String? = "Test" | ||
var firstChar: Char = test!!.get(0) | ||
// ^^ this way we just unwrap the value | ||
} | ||
``` | ||
|
||
### Rust | ||
|
||
As previously stated both rust and kotlin's systems works similar. The biggest difference most likely is the difference in handling the nullable value. | ||
|
||
#### 1. The safe approach | ||
|
||
```rust | ||
fn main() { | ||
let test: Option<&str> = Some("Hello"); | ||
// Test if the value is none or not-none. Match statement is pretty much the same as kotlin and nexus' `when` statement | ||
match test { | ||
Some(val) => println("{}", val), // print the value if it is not-none | ||
None => (), // do nothing if the value is None | ||
} | ||
} | ||
``` | ||
|
||
#### 2. The unsafe approach | ||
|
||
```rust | ||
fn main() { | ||
let test: Option<&str> = Some("Hello"); | ||
println!("{}", test.unwrap()); // We just use tha value and risk it being none. Luckily rust directly throws an error when trying to unwrap the value, before we can do even more damage | ||
} | ||
``` | ||
|
||
### Conclusion | ||
|
||
Personally I think having a mix between kotlin and rust's safe none handling would be be best so we will go with something along those lines. As for the unsafe approach however, I prefer rust. | ||
|
||
|
||
## Our own solution | ||
|
||
```kotlin | ||
const myVal? = none | ||
# ^ we use the question mark, similar to kotlin but without requiring the type | ||
|
||
when myVal? { | ||
none -> (), | ||
else -> puts(myVal), # we can safely use myVal now and dont need to unwrap it | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
# Setup | ||
|
||
1. Start by installing the Nexus interpreter from <https://github.com/MuffinGroup/nexus/releases> | ||
1. Start by installing the Nexus interpreter from <https://github.com/MuffinGroup/nexus/releases> [WIP] | ||
|
||
2. Install an IDE (Integrated Development Environment) or Text Editor like [Visual Studio Code](https://code.visualstudio.com/) or our upcoming editor [Void](https://github.com/MuffinGroup/void) | ||
|
||
3. Install an extension if nessecary [WIP] | ||
3. Install the extension if nessecary [WIP] | ||
|
||
4. Run the commands `nexus` and `matrix` in your console (Matrix is not yet part of the Nexus distribution) to check if Nexus is installed. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.