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
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.
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.
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.
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?
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.
Navigate
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
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.
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 justlen
.input_str
: receives justinput_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 if
s 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. 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
andafter: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.