Home

I write a lot about programming.

Using this

On the top-left, there is a Menu bar that looks like 3 lines. This allows you to navigate to the different sections of the website. Near it, there is also a paintbrush icon. Use this to change the theme of the website. There's also a search bar. Use it to search the website. On the right, there is a file icon. Use this to print the website. You can also press the arrows to go back and forward in pages. But this is not recommended. This is because this is not exactly a book. It's more of a website.

MCFunction Beginner Guide

  • This guide is for bedrock edition.

Beginner's Guide to Commands

read time

This guide is unofficial, to be accompanied with the guide here.
Firstly, since you're new I recommend reading to full.
I know that this is quite long, but I mean it's useful, and it can be accompanied with my other guide. You can contact me here

What are commands?


Commands are bits of text that the game Minecraft understands, they can get quite advanced, but they're easy to pick up and learn.

Why commands?


Commands are pretty much the only way to create Minecraft content, without a real coding language, and they're pretty cool.

Beginning


Firstly I'm going to cover some logic, this is probably the most important part.
There's a lot to cover, but I'm mostly going to be covering the beginner's basics.
In Minecraft, there are 2 types of things, as I like to think of them. Those 2 things are entities and blocks.
You might've heard of those a lot, and they're very important.

How to Read This This is kinda written weird, don't skip over any headers, unless you have full certainty of them.

Basics


Here are some of the basics, read above for a bit of how to read this.

What is a block?


A block is essentially an object that takes up a 1x1 space . An example of a block would be say grass, dirt, etc.
Everything in the below image is a block, don't worry about the water just yet.

an environment in Minecraft

What is an entity?


An entity as I like to think of it is any object that is not fixed to it's position, and can take damage.
Water isn't fixed to it's position, is it an entity? No, the reason for that is because water cannot take damage.
All mobs, but not only mobs are entities. Below is an example of an entity.

chicken.png

Now that you know what entities and blocks are, that's a step forward.

What is a syntax?


A quick explanation I'll give about syntaxes is that they're the format of the command, if your command doesn't
execute, then there's a chance it's that. Give all syntax errors a full read, if they don't work, take reference
from either my main guide or the /help <command-name> command while in game.
An example of a syntax error is: /kill @ e. That specific one will be raised because there is a space between the
@ and the e. We'll go deeper into these @ things in a bit. Below is an example of a syntax error.
This most likely happened because the person didn't put an argument afterwards, but don't worry too much.
error example

How do I read a syntax?


Here's a quick sumnary, it isn't really accurate (I personally don't read them and somehow know it):

  • <text_here>. These brackets mean that this argument is required.
  • [text_here]. These brackets mean that this argument is optional.
  • (option1 | option2). These brackets mean that this argument must be one in the list.

Coordinate Management


This is a crucial part in commands.

What are coordinates?


To put it in my way, coordinates are really just the location of an object. But how do you know the coordinates?
How are coordinates formatted? Well, regarding both of them, there are three axes, namely X, Y, and Z.
How are they formatted?
The X and Y axes should be clear, otherwise click on the hyperlink.
Things start on the Z axis , that's what different, it's kind of like X, think of it as just another X, the reason
for the existence of the Z axis is because the game is in 3D, don't worry too much about it for now.
How does one get the coordinates of an object?
It's quite simple to do this, you do not need to teleport yourself. You can simply run this command:
/gamerule showcoordinates true and your coordinates should show at the top left. Once they're showing, read the numbers after
Position. It should look somewhat like this: Position: X, Y, Z. If it doesn't show exactly like that, don't panic.
X, Y, and Z are used to represent the number, whatever it is , is where your legs are . We'll be getting into
tildes on the next section, they will be necessary.

What are Tildes?


Tildes are the ~ character, which in English means about, near, or here.
Same thing goes for coordinates in Minecraft.
Each tilde in a command represents from where the command is being executed, and Math can be done on those.
To add to the coordinate: ~<number>. This goes for all X, Y, and Z axes.
To remove from the coordinate: ~-<number>. Note the -. This goes for all axes.

Say you want the player to teleport 10 blocks upwards, remember the Y axis is vertical.
tp <target> ~ ~10 ~.
Now what is target you may ask. Target means the entity the command is being executed on.
This command moves the player 10 blocks up from the command block if there is one, or the person who executed it.
Don't worry yet about making the player do it, we'll cover it now.

Entity Management


Well this is a bad name for the section, but this section is for managing entities.
There are a lot of commands that can affect entities, but here I'll cover the crucial ones.

Deleting an Entity


It's very easy to delete an entity, you can simply use the kill command to delete an entity.
But what if you wanted to delete a dropped item, or perhaps a specific mob? Below is more info.

Targetting


You can use the target selector argument, which I will be specifying information about right here.
You can use the @e targetting, but further than that is what we'll be focusing on.
@ Target Selectors
Now what are these? Well, I like to explain these as the main argument in selecting which entity to use.
A list of each one of them, and what they do is below:

  • @p This selects the nearest player from where the command was executed.
  • @r This selects a random player in the world who is online.
  • @s This selects the entity that executed the command.
  • @a This selects all the players.
  • @e This selects all entites. @s is one I just wanna talk a bit more about. It makes the entity that executed be executed on.

For example, I want a creeper to say Aww man in the chat, I'd use:
execute @e[type=creeper,name="creep.er"] ~ ~ ~ say Aww man.
You see those things in the [] brackets? They will be covered next.

@e[type=<entity_type> will select a specific type of entity, this could be TNT, a dropped item, a
specific mob type, etc, it can find any entity type. But what if you wanted a specific entity?
@e[type=<entity_type>,name=<name>. With that, you'll find one of a name.
A very common issue I find others doing is when they're getting the name, they usually
forget to add quotes after the = sign. If the mob has a space in the name, simply
instead of <name>, imagine it becomes "<name>".
The name may be ugly, and so here is an alternative, this is also a way to group entities. /tag <target> (add | remove) <name: string>.
This will add a new group to the targetted entity, after adding it you can remove the name, if there is one.
Now string means to add quotes, just like the name in the target selector.
You may want to check for the range, here's how: @e[r=<range number>]
In most guides, number will be represented as int or integer. They both mean a number.
In the case of a decimal, it's considered float.

Execute


This is an extremely important section! This section is fully dedicated to making entities execute a command, think of it as sudo, but for commands.
The execute command is the most powerful command in the entire game, but don't worry, it isn't hard to
pick up on. /execute <target> <location> <selected command syntax> is the syntax.
The location argument will be discussed a bit below.
<selected command syntax> refers to the command you're getting the entity to execute. I always have my location as ~ ~ ~ and when it's
like that, it executes anywhere, that's at least what I use for myself.
But what if you wanted to check if someone was on a specific block type?
/execute <target> <location> detect <block to detect> <data value> <detectPos> <command>.
That would be your syntax.
detect isn't in brackets, this means to just put it there, regardless.
Say you wanted a creeper walking on grass to kill nearby ocelots, you'd use this: /execute @e[type=creeper] ~ ~ ~ detect grass 0 ~ ~-1 ~ kill @e[type=ocelot,r=5]

Now that you've gotten this far, I believe you're ready for my other guide, which has a contents panel.
Click here.
Also quick notice, use the power of effect, armor stands, tags and names.

Exporting your Map


There's a guide for functions in my other guide which is linked a bit above as a hyperlink.

Visit here to see how to. Give me feedback in the comments!

You can take a look at some examples.

Reference for Minecraft Commands

What is this?

readtime
This is a documentation for Bedrock Minecraft commands, which is unofficial, written by VideoCarp.
Visit Navigate for easy navigation between commands.
Are you a beginner?
If you've not been redirected from my other guide, click here for my beginner's guide.
To show your appreciation, you can star this gist, or comment with feedback.
Hate? Give me feedback in the comments, or by contacting me through my server (check below headline)

Can I distribute this guide?

Please don't. Always put the link to this direct mdbook, the gist or otherwise contact me on discord, at my server.

Unofficial Mcfunction Documentation

This is also for commands, so do take it for that reason, this is not an official guide. A dictionary is at the lowest part of the documentation, take a look at that if you do not understand some words.

Fully Entity Related Commands:

Execute

The execute command is used to force entities to run commands. The command’s syntax is as the following without detect.
/execute <target> <location> <command> <selected command syntax>
The syntax with a detect is as the following:
execute <origin: target> <position: x y z> detect <detectPos: x y z> <block> <data: int> <command>
If the entity detects the block to detect on the detect position, the command will be executed.
Gamepedia: Click here to see gamepedia.

Testfor

This command tests for entities, it can be used to activate conditional command blocks. If the testfor command finds the entity, the command is successful.
This command can also be used to count entities.
Command syntax:
/testfor <target>

Spreadplayers

This command teleports entities to surface within a specified area.
Syntax:
/spreadplayers <x: value> <z: value> <spreadDistance: float> <maxRange: float> <victim: target>

Tag

Controls scoreboard tags for entities.
Other Info regarding ”tag”:
This can also be used to add certain tags on entities in the [tag=tagname] entity selecting part.
Syntax:
tag <entity: targets> <add|remove> <name: string><br> tag <entity: targets> list
This command could be used to set-up a restriction for users other than OP. However, regular commands cannot change
permissions

Block Related Commands

Testforblock

This command tests for whether a certain block is in a specific location. See testforblocks
(with an S) for multiple block testfor. This command can be used to activate conditional command blocks.

Command syntax:
testforblock <position: x y z > <Block> [dataValue]

Testforblocks

This command tests whether the blocks in two regions match.You can use this for conditional command blocks.
Command syntax:
testforblocks <begin: x y z> <end: x y z> <destination: x y z> [masked|all]
Arguments in masked/all.
Specifies how to match blocks. Must be one of:
all — every block in the source and destination regions must match exactly.
masked — air blocks in the source region will match any block in the destination region.
If not specified, defaults to all.

Setblock

Setblock is a command that places a block at the specified location.
Syntax:
/setblock <location> <block> [data]}

Fill

Fill is a command that places blocks from a specified location to another. /fill <from: x y z> <to: x y z> <block> [data].

Other

Effect

This command can add or remove status effects on players and other entities.
You know what effects are, they’re just potion stuff.
Syntax:
Clear Effects
effect <player: target> clear
Add or remove an effect
effect <player: target> <effect: Effect> [seconds: int] [amplifier: int] [hideParticles: true/false]
Amplifier is the level of the effect. eg: strength 5 (amplifier).



Teleport

The teleport command teleports entities to a specified location, or another entity.
Syntax Laws:
Entity/ies can be teleported at once to one target.
If an entity is requested to teleport to more than one target, the condition will fail.
This can be used to determine if a mob has died.
Multiple entities can teleport to one coordinate.

Command Syntax:
teleport <victim> (location | target)
Advanced usage of the syntax is very complicated, click here
for more information regarding advanced usage of the syntax.

Summon

The summon command is used to spawn in new entities into the world.
Entities such as TNT can also be summoned with the /summon command.

Syntax:
With spawn event

summon <entityType: EntityType> [spawnPos: x y z] [spawnEvent: string] [nameTag: string]
Without spawn event

summon <entityType: EntityType> [nameTag: string] [spawnPos: x y z]

Clear

The clear command is a command used to remove items from a player’s inventory.
Syntax:

/clear <target> <item name> <data: integer> <maxCount>
The data interval makes sure that the item matches the data interval, or the command will fail, this will not a trigger a
conditional command block.
To test for an item in a player’s inventory, use the following syntax:

/clear <target> <item name> <data> 0

The 0 will replace the command instead of deleting an item from a player’s inventory, it will check for one.



Give

The give command allows users to obtain items normally unobtainable, or items that already
are through commands.

Syntax:
give <player: target> <itemName: Item> [amount: int] [data: int] [components: json]
The cans for that are: (on bedrock)
{“can_place_on”:{“blocks”:[“BLOCK”]}}
{“can_destroy”:{“blocks”:[“BLOCK”]}}
Available arguments (gamepedia)

Tellraw

This command sends a raw json message to the specified target. This appears without any external text, the message appears in chat alone, unlike a /say message. Command Syntax (bedrock): /tellraw <target> <raw json message> The raw json message field is to be filled with something like this {“rawtext”:[{“text”:”your text”}]}

Title

The title command shows text onto the middle of the player’s screen, their action bar or under it as a subtitle. Syntax:
/title <target> (title | subtitle | actionbar) <text>
View gamepedia syntax

Particle

Particle is an extremely useful and decorative command in Minecraft. It just adds cool particles and overall
adds character. The syntax for it is:
/particle <effect> <location>.
But what if you wanted to use the location as a target entity? You can use the execute command for that.
You can see a list of effects you can use here.

Scoreboard

Scoreboard is an interesting command. It's also a very confusing one. Scoreboard is used to store the score of
players in Minecraft, or maybe even entities if that's possible.
To add an objective, use:
/scoreboard objectives add <objective: string> dummy [displayName: string]
and to change the value of an objective, use:
scoreboard players <set|add|remove> <player: target> <objective: string> <count: int>.
There are a lot of things, but those are the most basic.
See gamepedia for more information.

Non-Commands

Conditional

Conditional command blocks are command blocks usually used in chains are command blocks that
only work if the condition is met.
These can be used in chains for shop systems and such.

Scroll down in official gamepedia a little bit
until the Condition headline.

Manifest

The manifest is a key file in all resource packs, worlds, behavior packs, etc. The manifest is what allows the pack to show on the list. Sources:
Bedrock Manifests
Bedrock Resources Manifest
Bedrock Behaviors Manifest

Functions

Functions are a way to kinda import a ton of commands into new worlds easily, unlike command blocks however, they cannot be conditional.
When you run the function command, it executes the .mcfunction file named by your argument.

For example, a file named cool_file.mcfunction will execute if you return the argument as cool_file in other words,
/function cool_file , however, if a different argument is written, the game will search for the .mcfunction named by
that, if none, the command will fail.

.mcfunction files are always filled with nothing but commands.

Now for the folder setup.

Bedrock Edition:

(your pack name):open_file_folder:

(functions):open_file_folder:, <manifest.json>📄 , <pack_icon.png>📄

<filename.mcfunction>:page_facing_up:

Don't understand what each bracket means? Read the dictionary at the bottom.

Dictionary

How to Read Guide:
1. Syntax
This means the format the command is used in.
2. Manifest
This is the file in which you’ll have for things such as texture packs or bedrock edition addons.
3. <> bracketing in syntax
This means that this part of the command is required for the specified use.
4. () bracketing in syntax
Separated by |, this means that this part of the syntax must be one of the things within the brackets.
5. [] bracketing in syntax
This means that the part of the syntax is optional.
6. Target
This is the entity the command is being executed on.
7. Entity
An entity is a mob, a player, a dropped item, an armor stand, falling gravel/sand or anything in the game
that isn’t in a completely solid state and fixed to it’s location.
This may not be the best explanation for an entity, but you get the point.
8. File Bracketing
I use this to define a folder. Eg: <file>, (folder)
In some cases I may also have an icon. ":page_facing_up:" means file, :open_file_folder: means folder.
9. Integer Normal integers are really just digits. In this case, integers are numbers still, but must be valid data values.

Tags

Google search tags: gist github mcfunction minecraft commands bedrock edition mcpe mcbe mc pe pocket edition learn commands function-pack videocarp guide syntax execute documentation docs carp video game minecraft learn commands syntax bedrock minecraft

Exporting your Map

Follow the process below.

Finding your Directory

Click the > like thing to expand.

Windows 10 Open up the "Run" app, (shortcut Win+R) and insert this.
`%LocalAppData%\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\games\com.mojang\minecraftWorlds`
This will find the Minecraft Windows 10 Edition directory and you will see some folders here.
iOS Use the "files" app and find 'On my iPad' or 'On my iPhone', find Minecraft.
Now navigate like this:` games -> com.mojang -> minecraftWorlds`
Android Use any file explorer app, and follow this path:
`/sdcard/games/com.mojang/`

Continuing

This part is for how to do the rest after finding your minecraftWorlds folder.

Now that you've found your minecraftWorlds folder, select a sorting option for your folders. Preferably, if available sort by which was last edited, tne most recently edited one, if you exited properly should be the correct map, read the level_name.txt file, if it has the correct name, Now, you would need to have some way of compressing and renaming files, renaming files should be covered for Windows and Android, for iOS, use iZip. it is the correct world. Now that you have the exact folder, and the correct apps you need for your map, follow this process:

  • Compress the contents of the folder. Zip the contents of the folder, not the folder itself, otherwise your .mcworld will fail to import.
  • Rename to your_map's_name You don't need to make it match anything, just use plain text. Do not use §eYellow for example, it is unecessary and makes your installer look bad.
  • Change the zip file's extension to .mcworld You've got your compressed folder now set up. Try testing it!

Lexing for beginners

readtime

This is a guide that should teach you how to perform basic lexing in a functional programing language. Everything was written in Elixir, but you should be able to follow it if you are using any functional programming language. Or even an imperative programming language like Python, C or Java.

What is lexing?

The first question you should ask yourself is, what is lexing? It's the same as tokenising, scanning or lexical analysis. That might not help you if you haven't heard of these either. Put simply, lexing is the process of breaking down a string into meaningful units, indepdendent of context. What a lexer will do is make the following happen:

# Turn this:
# out("Hello World!")
# into this
[
    {"out", :identifier},
    {"(", :oparen},
    {"Hello World!", :string},
    {")", :cparen}
]

To further help you understand what lexing really is, take a look at this diagram. Don't worry if you don't understand the terms used.

702430A0-1D90-419F-B615-455199B20EAC

If you still don't understand lexing, think of it in this way: you have a sentence in English. It's "Lexing is not easy, but it's possible." You can break this sentence down into its words, "lexing", "is", "not", "easy", ", ", "but", "it", "'s", "possible". And then you can categorise each word. Like adjectives, verbs, etc.

  • Lexing can be done on any language, from English to C.
  • Lexers don't care about most errors, and they can only handle a few.
  • When developing a programming language, lexical analysis is the first step taken.
  • Lexing allows graphemes (characters) to be morphed into morphemes (small units of meaning).

Why lex?

Why would you ever need to break down a string into meaningful units? And why do this process when I can just use regex with split functions? The answer to that question depends on what you're trying to do, and why. Generally, regex is much slower than by hand lexing, you have to follow its rules and it's less powerful than doing this by hand. Furthermore, lexing is a great exercise. In fact, once you understand lexing, you'll understand all language a little more. Should you lex? I recommend you do if you are writing a language or analysing one. But if you feel like you should lex, then do it.

IMPORTANT

I highly recommend you do not directly copy and paste any pieces of code. It will hinder your learning. If you want to change anything, then do it. Play around with the functions and if you are wondering anything, try it and see.

How to lex?

Theory

I'll begin by discussing some theory behind lexing. A lexer is supposed to somehow understand what things are meaningful units of language, which can seem easy at first, but later seems near impossible. The first thing to discuss is that there is no universal tokenisation model, as long as it is efficient and generates the desired output, your lexer should be fine. So, let's try lexing the following: number += sqrt(16)

We want this to become something like

[
    {"number", :identifier},
    {"+=", :assignment},
    {"sqrt", :identifier},
    {"(", :oparen},
    {"16", :number},
    {")", :cparen}
]

This is a list composed of tuples. On the left hand side is the raw unit of meaning, and on the right is its category. I'll call them the token and tag, respectively. The tag is of the type atom , which you don't need to worry about. A scanner will work perfectly fine, had they been strings instead. In this case, I just preferred using atoms.

Terminology

  • Identifier An identifier is things like a variable or a function name. They are referencing something.
  • Assignment An assignment just means that this is an operator that is used to assign a value. An operator is a symbol placed between identifiers or values to do something.
  • Oparen Oparen is short for "opening parentheses." Parentheses are "(" and ")."
  • Cparen Cparen is short for "closing parentheses."

Writing code

The next step is to implement the lexer. Because this is a guide using a functional programming language, Elixir, recursion will be used rather than looping. But don't worry if you're an imperative developer, I actually found it easier to use recursion for lexing than loops. I'd recommend lexing with a functional programming language if you are using this guide. You can easily link it to whatever language your main program will use with files. Recursion, simply, is when a function calls itself. When a function calls itself, it goes back to the start of the function, much like a continue in a loop.

Elixir requires all functions to be in modules. So that's where we'll begin.

defmodule Lexer do
    def lex(current  \\ 0, tokenstream  \\ [], len, input_str) do
        char = String.at(input_str, current)
        unless current >= len do
            cond do
                ...
            end
        else
            tokenstream
        end
    end
end

This may not make sense just yet, so I'll explain every line here. defmodule Lexer do : this defines the "Lexer" module. Be absolutely sure you name your module in uppercase, otherwise everything will break. def lex(current \\ 0, tokenstream \\ [], len, input_str) do : this line defines the lex function and its parameters. The \\ sets the default arguments for each parameter in Elixir. The current variable is the index on the program the user inputs, which is input_str . len is the length of input_str . char = String.at(input_str, current) : this line defines the char variable. This variable is the substring which we are testing conditions for. String.at(input_str, current) is equivalent to input_str[current] in other language such as Python. unless current >= len do : unless current is greater than len , do the following. This is equivalent to if !(current >= len)

or if not (current >= len) in other languages. This is crucial because it ensures that recursion only happens when it needs to. This effectively means if the string has not been exhausted. cond do : this is a block of code that can have conditions attached to it. This is an equivalent of a block of if s and else if s. ... : this means that we'll fill this section later.

else
    tokenstream

This is not a single line. But this is the else block for the unless . This means that this code will execute once the string has been exhausted. And we return tokenstream . In Elixir, the last expression's return value is what the function will return. In other words, it's the same as return tokenstream in other languages. The rest are end s. These terminate blocks. They are equivalent to unindenting in Python or } in a lot of languages.

Adding helper functions

In most programming languages, identifiers are defined using the English alphabet, numbers and _ , numbers are written as the Hindu-Arabic numerals (0, 1, 2, etc.) and strings are written using quotes. Functions are called with parentheses, and so on. Elixir allows using ? in identifiers. And the magic that makes this happen, is of course in part the tokeniser. To allow you to tweak and debug your lexer easily, as well as be more concise, helper functions are ideal. So, what is a helper function? In this context, a helper function is a function that takes as input a character and returns a boolean. It checks for a condition using the character. These are easily the simplest part of the scanner. I'll start with a few helper functions, and more will be added. Nest these functions in the lexer module.

def numeric(char) do
    char >= "0" && char <= "9" # Characters are just organized conveniently. && means "and."
    # This function tells us if "char" is a number. It obviously doesn't cover floating point numbers,
    # but you should be able to add them if you need to.
end

def alphanumeric(char) do
    numeric(char) || (char >= "a" && char <= "z") || (char >= "A" && char <= "Z") || char == "_"
    # This checks if the character is alphabetical, numeric or is equal to "_".
    # This will be used to create identifier tokens.
    # You can add other conditions to add more characters. But be sure to use a "||" (or).
end

def arithmetic(char) do
    Enum.member?(["+", "-", "*", "/", "%"], char)
    # checks if character is used for arithmetic operations.
    # if it is in that list.
end

There are explanations on what each of these functions does and how. But these are a foundation for the basic lexical rules of the language. Be sure to nest these in the Lexer module, so that they're local and accessible by the Lexer.lex function.

Simple symbol lexing

So now you have the tools to easily identify where each character belongs. You don't need to use these helper functions yet. But you may have noticed that symbols like "(" or "=" were not covered with the helper functions. These things are oftentimes single-character tokens, so it's not worth making a function we'll never use or edit. How do we add the single-character tokens with their tags into the tokenstream? The answer to this is simple: by checking a condition and performing recursion. What will be done is that when one of these is encountered, lex will be called with new arguments. Remember the arguments to lex ? They were current , tokenstream , len , input_str . It may not make sense that our lexer function wants to take its own output as an argument to an imperative programmer. However, it's a crucial part of using recursion with immutable variables effectively for lexing. What we'll do is call the lex function again when we spot one of these single- character tokens.

  • current: receivescurrent + 1, which is our cursor plus the amount of characters we went over.
  • tokenstream: receives [{char, :TYPE} | tokenstream]. This is prepending (adding as the first element or head of a list) a tuple containing the character and the category. :TYPE means the tag. If appending is available, I highly recommend it instead. In Elixir, prepending and then reversing is faster than concatenating lists, so that's what's being done here.
  • len: receives just len.
  • input_str: receives just input_str.

Let's put this in real Elixir code. Inside our cond block, it should now look something like this:

                # single-char tokens
                char == ")" -> # if the condition is true, do this.
                    lex(current + 1, [{char, :cparen} | tokenstream], len, input_str)

                char == "(" -> # if the above was false, do this instead. and so on
                    lex(current + 1, [{char, :oparen} | tokenstream], len, input_str)

                char == "{" ->
                    lex(current + 1, [{char, :obrace} | tokenstream], len, input_str)

                char == "}" ->
                    lex(current + 1, [{char, :cbrace} | tokenstream], len, input_str)

                char == "=" ->
                    lex(current + 1, [{char, :assignment} | tokenstream], len, input_str)

                true -> # if all the conditions failed, do this instead.
                        # this is what should happen if an unknown character is found.
                        # Here, it's being ignored. But you can raise an error, if you wish.
                    lex(current + 1, tokenstream, len, input_str)

If you give your lexer a try now, which you can do by printing Lexer.lex 's output with IO.inspect , it should be able to scan any of these characters, but ignore everything else.

Handling multiple-character tokens

Remember the helper functions you defined a bit ago? Here's where they're going to come in useful. The first step to handling multi- character tokens is to define some functions to do that for you. This is advantegous in that it increases your code's maintability significantly in comparison to just doing operations. And it's a lot simpler, too. The main idea behind handling tokens > 1 character is to go over each character, add it to a temporary string variable until calling the relevant helper function with the character argument doesn't return true, or the string is exhausted. Then, that temporary variable is passed into the token stream with a tag. This is a lot easier done than said (not a typo) but that was my best explanation. Let's start with lexing integers. Define the following function nested into Lexer .

    def handlenum(cursor, temp, input_strr) do
        # `cursor' is the same as `current', but to make sure they're distinguished, I use `cursor'
        # `temp' is a temporary variable that begins as an empty string.
        character = String.at(input_strr, cursor)
        if numeric(character) do
            handlenum(cursor + 1, temp <> character, input_strr)
            # if the character in this recursion is numeric, then go back up
            # but go to the next character and add to the temporary variable
        else
            {temp, cursor}
            # return a tuple of the token and the new cursor.
        end
    end

Closely inspect this, and once you get it, write the rest:

def handlestring(cursor, temp, input_strr) do
        character = String.at(input_strr, cursor)
        if character != " "" do
            handlestring(cursor + 1, temp <> character, input_strr)
        else
            {temp, cursor}
        end
    end

    def handlealpha(cursor, temp, input_strr) do
        character = String.at(input_strr, cursor)
        if alphanumeric(character) do
            handlealpha(cursor + 1, temp <> character, input_strr)
        else
            {temp, cursor}
        end
    end

What you will notice, is that the process is quite simple. Each one of these is largely the same as the others, just with different conditions. In fact, these functions could've been generated with just one function. But for the sake of simplicity and performance, this will be sufficient. It's important to note, if you don't yet understand, don't go to the next part yet. It's quite normal and as to be expected that you don't fully understand lexing the first time. So, don't worry and keep trying.

Implementing the handler functions

You should now be able to shove these handler functions that depend on the helper functions into your cond block in Lexer.lex . Give that a shot and try running your program. It should work if you filled everything in correctly. You should've added something like the following in your cond block.

                char == " "" ->
                    {token, cursor} = handlestring(current + 1, "", input_str)
                    # Increments to manage the quotes. We don't want them.
                    lex(cursor + 1, [{token, :str} | tokenstream], len, input_str)

                numeric(char) ->
                    {token, cursor} = handlenum(current, "", input_str)
                    lex(cursor, [{token, :number} | tokenstream], len, input_str)

                alphanumeric(char) ->
                    {token, cursor} = handlealpha(current, "", input_str)
                    lex(cursor, [{token, :identifier} | tokenstream], len, input_str)

Make sure to add this above the true -> segment. If we give lex our program, that was intially number += sqrt(16) , the output would be:

[
    {"number", :identifier},
    {"+", :arithmetic},
    {"sqrt", :identifier},
    {"(", :oparen},
    {"16", :number},
    {")", :cparen},
]

This isn't exactly what we want. It ignored = and added an arithmetic out of nowhere. += should've been {"+=", :assignment} . Fortunately, the solution is easy. It will be explained in the next section.

Conditional multi-character tokens

Sometimes, you need to lex something that could be one thing or the other, or both. For example, += should be an :assignment

rather than :arithmetic , :assignment . While + = should be :arithmetic , :assignment . The solution to this is by something called "peeking." Peeking is exactly what it sounds like: you look at the next token without actually advancing to the next character. Knowing that, the idea for scanning += correctly is simple: when you find a + , peek for an = . If there is, advance twice and add the token with the tag. Otherwise, add the + alone. So, add this to your cond block.

                arithmetic(char) ->
                    unless String.at(input_str, current + 1) == "=" do
                        lex(current + 1, [{char, :arithmetic} | tokenstream], len, input_str)
                    else
                        lex(current + 2, [{char <> "=", :assignment} | tokenstream], len, input_str)
                    end

But about the = ? Well, do the same thing if you're going to have an == which should be a :comparison . Or, do the same thing as you did in the start with single-character tokens suh as :oparen .

Almost done

After that's been done, you're almost done with a basic lexer that you can build on. All you have to do now is go to the else within Lexer.lex 's unless and replace tokenstream with Enum.reverse(tokenstream) . And that's it. But be sure to read the rest.

Notices

This is an imperfect lexer and has been slightly simplified. Rather than "consuming" the input string, here, we're actually just indexing it. This is inefficient but it should be sufficient for a lot of cases. Click here for the finished lexer. If this helped you or you'd like to give some feedback, please contribute or post a comment.

Introduction to Programming

Who's this for? This is for anyone interested in programming, who has found it difficult to get started. What this book covers:

  • Why program?
  • The basic information needed to get started with programming.
  • The different ways of programming.
  • The art of Googling.
  • Picking a programming language.
  • Fields to program in. What this book does NOT cover:
  • How to program in a specific programming language
  • Advanced programming theory Programming is a wide, complex subject. And it isn't easy to start programming, because the terminology used can often be confusing. This book aims to fill in many of the gaps, and empower readers to overcome these barriers and become skilled Google users.
Maths You might've heard that you need maths for programming. This is *kinda* true, but also not really. You need maths if you do AI or data science. But you don't need maths to make a website. There is some mathematical theory in programming, but it's not complex, so don't worry. The maths you need for programming depends on the subject, but in general, it's not hard.

Why program?

Why should you program? This is the first important question to ask yourself. Are you interested in programming? Perhaps you're a student? For work? Whoever you are, programming is an enriching subject, that once understood, will be a useful or even fun tool to use. Programming may appear an impossible task, but don't let that affect you. It's just hard to get started.

ℹ️ Some subjects are very difficult in programming, but you'll find a lot are easy.

The practical uses of programming:
Programming is applicable in a variety of fields and sometimes you don't even know you're using a program. Programming is used in engineering, medicine, science, making applications, websites and plenty of others. In regards to what programming can achieve, the answer is ”anything.” Any task you can think of, that can happen, can be programmed. Websites, applications, operating systems and general appliances are or can be programmed. In short, programming is useful if you need to make something happen. Programming as a hobby:
Programming can be a hobby, too. It can be an eye-popening activity, that will change your thinking for the better. And help you understand things around you. It's not easy to describe it.

Programming basics

Thinking programmatically:
The first step to get into programming is to understand how to think about it. First off, a "program" is a series of instructions to be executed by a computer. This definition has some programming terms. Simply, a "program" is a bunch of code that can be ran by a computer. Sometimes, programs are used the same as "source files," which are files that contain code written in a programming language. So a program is what the computer understands and a source file is what you write. It's not too important to disting uish these terms at this point, but you can.

ℹ️ Collections of source files or programs that you might use to write a program can be known as "libraries" or "modules." Note that "libraries" have a shorthand: "libs."

So now you have a basic idea of how files are organised when programming. Another important part of thinking like a programmer is to consider everything to be ordered instructions you give the computer. You tell the computer to show "Hello World!" on the screen, it shows that. Think of it as telling the computer to "do this, then do that."

ℹ️ You aren't telling the computer what to do in most cases. You're telling the programming language you're using to do that for you. If this doesn't make sense, do ignore it. Learn what's known as "computational thinking" if necessary; it's very useful.

Understanding what coding really is:
Coding has a fuzzy definition. But I would define it as creating a representation of what can end up being a program later. So, things like Scratch still count as code and writing code in files counts too. When you program, make sure to think of it as that. Writing code:
To recap:

  • Program: something that the computer can execute, usually generated from a source file

  • Source file: a file that is given to a programming language to make a program

  • Programming: creating a representation of what can end up being a program. This won't help you much, yet. So, let's understand how to write code. In general, you'll find these patterns in most programs.

  • Functions

  • Arguments

  • Parameters

  • Variables

  • Constants

  • Immutables

  • Mutables

  • References

  • Types

  • Strings

  • Integers

  • Floating-point numbers

  • Lists and arrays.

  • Tuples

  • Control flow

  • If statements

  • While loops

  • For loops

  • Arithmetics: they're just maths. This can look overwhelming. But once you get these, you'll find reading other docs a lot easier. Let's begin with the simplest: variables. Variables are like pronumerals in maths, only they can be multiple characters.

Variables

A variable is a name for a value. For example, imagine a variable named pi with a value of 3.14159. Now, when you write pi, you get 3.14159. There are 3 basic kinds of variables, and they can be confusing. The most common are mutable variables. For example, you define a variable named x as 5. Then, you change x to 2. Of course, because programs execute in order, all code before you changed x to 2 will result in 5. Unlike maths, variables can be defined in terms of themself. So, if you had changed x to be x + 1, it would have been 5 + 1, which is 6. Think of "mutable" as "mutate," which means change.
The other kinds, immutable and constant variables can't change. They're not the same, but I won't confuse you.

References

References are simply when you write a name for something, like an identifier or a function. Not much else to say.

Functions

Functions are used to name and reuse bits of code you have written. For example, imagine a program that adds 5 and 2 and outputs it, but you want that to happen many times, not just once. In this case, one solution would be to use a function. You'd name your function whatever you want, with parameters and a body. Parameters are variables that can take arguments from the programmer calling the function. Arguments are just any value that will make sense in the function's body, at the simplest level. The function's body is the code inside it.

For example, imagine a function named add1 with the parameter num and the body return num + 1. If you call add1 with 1 as the argument for the parameter num, then you'll get 2. return usually means what the function should result in. This is kind of similar to functions in mathematics, for example f(x) = x + 1.

Control Flow

I want something to happen only if a certain condition is met. How do I do that? By using what is called an if statement. An if statement is composed of a condition and a body. A condition is exactly what it sounds like. For example, an if statement with the condition that pi > 3 and a body that outputs "Pi is greater than 3" would run, only if pi is greater than 3. if statements can be accompanied with else and else if bodies. else only happens if all conditions fail, and else ifs only happens if all conditions above it fail.

What about if I want something to only happen while a condition is met? That's why the while keyword exists, and it's pretty much the same as if in terms of use.

What if I want something to happen a set number of times? Here, you can use a for loop. The way they're used is different in different programming languages, but generally, there is what's known as a control variable and the number of iterations. A control variable is a variable that changes every time the body of the for loop is repeated that you can access. Iterations are the repetitions of the body of the for loop.

Collectively, these are called control flow.

Types

Types are something you will hear a lot about in programming.

  • Strings: text
  • Integers: whole numbers, negative or not
  • Floating-point numbers: numbers with a decimal place
  • Lists and arrays: multiple same-type values that can be referenced using one name
  • Tuples: multiple values that can be referenced using one name There's also "typing," which doesn't refer to writing in a computer, but how types are default with.
  • Dynamic typing: a variable's value can change type, and a function's parameters' values as well as its resulting (return) value can change type.
  • Static typing: a variable's value cannot change type, a function's types cannot change

Different ways to program

In programming terminology (the terms used), different ways to program are known as paradigms. The most intuitive in my opinion is procedural, imperative programming, which is what you have probably been using.

  • Imperative: concerned with the "how" of the program
  • Procedural: oriented towards programming-style functions. It is a sub-paradigm of imperative. There's also object-oriented programming, which is quite common too.
  • Object-oriented programming: oriented towards "objects." It is a sub-paradigm of imperative. And there are declarative programming sub-paradigms, such as functional and markup.
  • Declarative: concerned with the "what" of the program.
  • Functional: oriented towards mathematical-style functions and immutable variables. It is a sub-paradigm of declarative.
  • Markup: used to show meaningful imagery.

This book mainly focuses on imperative programming, and I suggest you stick to it for now. It's not in the scope of this book to discuss at length programming paradigms, but if any interest you at some point, then do search them up. I'll discuss a little more in the "Picking a programming language" chapter.

The Art of Googling

What really is googling? To keep Google happy, I define googling as the use of the Google search engine to get information on any subject. And programmers google a lot more than you'd think. In fact, googling is the most important skill for a programmer to have. You google to learn a new programming language, a new library, to figure out what's wrong with your code, to find help and so much more. So, how do you google effectively? Googling is a skill that can be cultivated over years of experience. But the good news is, because you aren't yet a skilled googler, you can boost your skill quickly.

How do you do that? By using the google search modifiers syntax. They might have their own name, but I'll just use this. "Syntax" simply means the way something is written. Collectively, English's syntax is composed of its grammar, punctuation, vocabulary, etc. Google's search refinement techniques I got this image straight from Google, and you can see them there if you'd like. This image does not show all search modifiers, but I doubt you're going to be looking at social media for answers to your programming problems, save for Reddit. Do you ever find that when you're searching for something, you keep getting unrelated results? Or perhaps Google ignores some of your search query?

Both these are problems I frequently encounter while searching. But the solution's easy. If you don't want Google to ignore some words in your search query, wrap it in quotes, like this "GitHub pages". This will only return results that have the text "GitHub pages" exactly; the word GitHub has to follow the word pages. If you just want results that contain both, then use the search query "GitHub" "Pages".

Let's say you keep searching for stack exchange, i.e.: exchanging a stack. This is a model for search queries you're likely to make if you forget some terms. You'll keep getting results from StackExchange, the website and other websites that talk about it. So, now you try exchanging a stack. Alas, that changes nothing. A good idea here is to eliminate results containing "StackExchange." So, to your new search query, add -stackexchange. And now, you've found your result: swapping stacks.

Googling is tough. But here's a short, simple list on when you should use certain search modifiers and techniques.

  • Quotes: when you have an error. Be careful not to include the part where it says where the error happened in your code, though.
  • Minus: When you keep getting a result you don't want.
  • site:foo.bar: when you want to find an answer to a question that you lost.
  • before:date and after:date: when the results you get are useless because they're too new or too old. What websites to look for:
    It depends on the programming language you're using. But for most programming languages, try to find StackOverflow answers, GitHub projects or issues, and really any website you find.

Picking a programming language

This is a hole a lot of emerging programmers fall into, they just can't pick which language to get started. Well, I'm here to help with that. Picking a language is hard, because there are so many options. "I wanna do JavaScript, so I can do web development, but I don't like the language." Or "I wanna do Python because it has great libraries, but I don't like it." Lots and lots of things like that.

The real answer is, it honestly doesn't matter what your first language is. I tried starting with JavaScript, but I found it too confusing and ended up starting with Python. To this day, Python is the language I know most. But learning it was really difficult. At some point, I decided why don't I also learn other programming languages? So I tried. It was hard, but a lot easier. And now, I found learning Haskell, regarded as a difficult programming language, quite easy.

What I mean to say here, is you should start with whatever programming language you lean towards, even if you have doubts about it.
My controversial opinions:
I have some rather controversial opinions about which programming language to start with. This is the nature of anyone helping others pick a language to start with. I recommend beginning with a simple programming language, like Python, Lua, or Ruby. Start with a dynamically typed programming language, because types are a difficult concept.

Don't start with something like C#, Java or C++. C# and Java require you to understand object-oriented programming, which is a difficult concept for beginners and is highly controversial in the programming community. And they're both just simply hard. C++ is very difficult in comparison to other languages, too. My advice would be to start with a simple language, like one of the three I listed, and then if you want to, work your way to more difficult languages.

In truth, you don't always need to use difficult programming languages. You might hear that Python and Ruby are slow. And that's absolutely true. They are slow. But in most cases, it doesn't matter. Your user likely won't care. And Lua's really fast with LuaJIT, although Lua is not very popular. There are plenty of fast, simple programming languages, like Go, Julia and more. But unless you like their syntax, I'd begin with the simplest language I can find.

Obviously, this doesn't mean begin with HTML & CSS, because they're markup languages and likely won' help you understand others. Not to mention they're pretty frustrating compared to other code.

Picking a paradigm

Another hole programmers often fall into is choosing a paradigm. My advice is to do what you like. Do procedural programming if you like it, do object-oriented programming if you like it. But I'll try to give an overview of the advantages and disadvantages of some of the most popular paradigms.

Procedural:
Advantages:

  • Intuitive and simple
  • Widely supported
    Disadvantages:
  • Rare for some fields, like GUI.

Object-oriented: Advantages:

  • Used for GUI
  • Good for making libraries
  • Popular
    Disadvantages:
  • Complex
  • Clutters code (verbose)

Functional:
Advantages:

  • Very easy to debug
  • Concise
    Disadvantages:
  • Complex to get started.
  • Less widely supported.
    A lot of people will disagree with me here. I ignored any advantage or disadvantage that pops up in all 3. My advice would be to begin with procedural. It's really the simplest. Then you can dive into one of the other paradigms once you're experienced enough.

In summary: pick what you like and don't worry about it.

Fields to program in

I'll just list a few popular programming topics.

  • App development: GUI (generally object-oriented, but you can use other paradigms).
  • Web development: Frontend (what the user sees) and backend (managing the server and taking requests from the frontend)
  • Algorithms and data structures: I really can't explain it, so search it up.
  • Parsing: breaking down language into meaningful units (I have a guide on this in my website).
  • Concurrency: dealing with multiple programs running at the same time.
    and many more. It again depends on the language.

GUI in Rust

The Rust programming language seems like a good fit for GUI programming. C++ developers have access to Qt, wxWidgets and many more. It's considered that GUI is just not there yet in Rust. I tried using Iced, it seemed like a good option. But Iced's examples were not working. I didn't bother with other libraries, they were mostly GTK and webview. I gave it another try. And at least two options did work! egui and Tauri. You've probably heard of both of them.

Tauri

You might criticize Tauri for its performance. But you'd be wrong. Tauri is nowhere near as bloated as Electron and it allows you to use a Rust backend. You can call Rust from the frontend. One problem might be that Tauri requires you to use web technologies, such as HTML, CSS and JS. However, you kind of have other options. It's possible to use Fable with F#, ClojureScript or Go with GopherJS. There're also Pyscript and Brython for Python, which are extremely easy to set up. The problem here is that you don't get to use Rust for everything. If you're afraid of CSS and not JavaScript, check out SASS. And some frameworks you can use with to-js compilers might allow you to skip HTML.

egui

egui is a popular GUI crate for Rust. Contrary to Tauri, you can just use Rust. egui is in "immediate mode" style. This can be more concise and easier to reason about than you might think. In egui, something like this is possible.


#![allow(unused)]
fn main() {
ui.label(&mut self.labelcontent); // you define this.
if ui.add(Button::new("Click me!")).clicked() {
    self.labelcount = "You have clicked the button!";
}
}

As you can see, you can connect things concisely. This label is bound to self.labelcontent. When self.labelcontent changes, it will in the next frame. So it updates in what appears instantly. I found egui to be quite intuitive and I haven't yet found any problems with it. The only problems with egui that I know of are that it is not native (but it still looks great) and that updates have breaking changes.

Other options?

I've only tried Iced, other than these. Unfortunately, examples didn't work. Soon, this may be fixed. But for now, I suggest you try these out. If you aren't satisfied, perhaps look at docs.rs and search for GUI there. Also check out areweguiyet. You can also bind libraries from other languages. I strongly suggest giving many libraries a try until one of them works for you.

Functional piping and composition

If you've been trying to get into functional programming, there's a good chance you've heard of composition and piping. These concepts apply to point-free programming. This is an attempt at a simple, clear explanation of function composition and piping. I will write these examples in F#, but the concepts apply to other languages like Haskell. They just use different operators sometimes.

Prerequisites: basic programming knowledge. This explanation is going to be simple.

Piping
Let's begin with the simpler of the two (at least according to my experience): piping. There are two ways which you could pipe a value to a function. Forwards, and backwards. When you pipe forward, you are applying the left side of the forward pipe to the leftmost argument of the right side of the pipe. In F#, piping forward is done with the |> operator. This means that

"Hello World!" |> printfn "%s"
// is the same as
printfn "%s" "Hello World!"
// Another example would be
let add1 x = x + 1
5 |> add1
// is the same as
add1 5
// And
let add x y = x + y
5 |> (1 |> add) // 6
// Parentheses are used to clarify precende (order)

It simply applies the something to the first unfilled argument (if you read from left to right). In Haskell, the operator used for this is &. Piping backwards may be clear to you now. It's the same thing, but it's read from right to left. In F#, backward pipes are done with the <| operator. For example,

let subtract x y = x - y
subtract <| 5 <| 1 // 4
subtract 5 1 // 4

In Haskell, this is done with $.

Composition
Function composition is a lot simpler than it may seem. It's the creation of a function that applies a function to the result of another. In F#, composition is done with >> and <<. Like piping, >> is read left to right and << is read right to left.

let add1 x = x + 1
let multiplyBy5 x = x * 5
let addThenMultiply x = (add1 >> multiplyBy5) x
printfn "%d" (addThenMultiply 4) // 25
printfn "%d" (multiplyBy5 (add1 4)) // 25

In Haskell, . is used for function composition.

Why bother?
A fair question you might have is, why bother piping and composing functions? Well, piping and composition helps us clear up our code of explicit rules for parentheses. Consider the example for composition. The first one is easier to read. And if we reuse it, we save on writing extra code. It makes things easier. And what about piping? Piping has the same applications. Would you prefer Seq.toList numbers |> Seq.iter (printfn "%d") or Seq.iter (printfn "%d" (Seq.toList numbers))? Maybe you'd prefer the latter. But it's more idiomatic to use composition and piping sometimes. And sometimes, there's a function with a long list of arguments you need to supply, with long names. Would you prefer

AVeryLongFunction VeryLongArgument1 VeryLongArgument2 (x VeryLongArgument3AppliedToX) (VeryLongFunctionName VeryLongArgument4AppliedToVeryLongFunctionApplied)

or

VeryLongArgument1
|> VeryLongArgument2
|> (X VeryLongArgument3AppliedToX)
|> (VeryLongFunctionName VeryLongArgument4AppliedToVeryLongFunctionName)
|> AVeryLongFunction

There are cases where this does happen. Just look at some examples using Avalonia.FuncUI. There, we are saved by the piping operators.

Reviewing functional programming

Here, I'll cover review functional programming according to my experience when I tried it. I'll cover what advantages there are and what disadvantages there are. My struggles, and what I found easier, and finally a conclusion. This is not a scientific paper, and is based solely on developer experience, it's more useful if you're trying to understand developer experience. Hopefully, this will help you decide whether or not to try functional programming.
So, I originally started programming in general procedurally, with Python. It's important to note that functional programming and object oriented programming are not the only two paradigms -- contrary to popular belief. Procedural programming is largely very different to functional programming, so do keep that in mind.

When I started functional programming, I started with F#. I was careful to avoid imperative structures like control flow. And when I began, it was obviously quite difficult, but I felt the same way as when I started programming in general. It changed my thinking. And it will most likely change yours. If the well of programming seems dry to you, functional programming can be like rain.

Initially, functional programming was significantly harder to me than imperative programming, because I honestly didn't understand functional programming and my mind hadn't yet adapted. I found it difficult to deal with there being no variables -- there are immutables, but I find using 'variable' misleading when they cannot be varied. And it seemed impossible to iterate when I shouldn't use loops.

After some practice, I caught the idea of using recursion to repeat and the parameters of a function as control "variables." Things started becoming a lot clearer, and immutability wasn't so much a burden anymore. It felt different to writing imperative code... but what's the point?

I decided to write a lexer -- not important for you to understand -- functionally, because I had always used them to learn new programming languages. This task was always hard for me to do, until I tried doing it functionally.

I explored other functional programming languages like Haskell, and Haskell was a lot easier than most people call it out to be. And I explored the Lisp language family. I didn't have any practical uses for these, but they were still nice.

It also filled a lot of gaps I had when doing imperative programming. A lot of imperative or multi-paradigm languages, like Rust, Python or CoffeeScript had functional features I didn't know about, that were quite useful. It helped me understand None and Some, map and filter.

Nonetheless, some tasks were harder in functional programming, like using a hashmap or dictionary to keep track of things. And I had a concern: the memory cost of recursion. But this was never a limitation. The CPU usage was lower, though and you might chalk this up to language, but in most benchmarks, functional programming can be slightly slower, but use significantly less of the CPU.

Summary

The good

  • Rejuvenating and eye-opening
  • Often easier to reason about
  • Interesting

The bad

  • Sometimes more complicated
  • Recursion RAM usage (which was never necessary to worry about)

Should you try functional programming?

Yes, you should. Unless you have time constraints, functional programming can be enlightening. And it's not like you have to use it. You can learn the philosophy, at the very least. I'm not here to claim it's superior or inferior to use, I'm here to voice my opinion on whether it's worth a try.