This commit is contained in:
Miloslav Ciz 2023-12-22 00:43:13 +01:00
parent b931aa36c3
commit b6b5090c4c
5 changed files with 183 additions and 26 deletions

View file

@ -1,10 +1,10 @@
# Blender # Blender
Blender (also Blunder) is an "[open-source](open_source.md)" 3D modeling and [rendering](rendering.md) [software](software.md) -- one of the most powerful and "feature-rich" (read [bloated](bloat.md)) ones, even compared to [proprietary](proprietary.md) competition -- used not only by the [FOSS](foss.md) community, but also the industry (commercial [games](game.md), movies etc.), which is an impressive achievement in itself, however Blender is also a [capitalist](capitalist.md) software suffering from many not-so-nice features such as [bloat](bloat.md). Blender (also Blunder) is a greatly [complex](bloat.md) "[open-source](open_source.md)" 3D modeling and [rendering](rendering.md) [software](software.md) -- one of the most powerful and "feature-rich" ones, even compared to [proprietary](proprietary.md) competition -- used not only by the [FOSS](foss.md) community, but also the industry (commercial [games](game.md), movies etc.), which is an impressive achievement in itself, however Blender is also a [capitalist](capitalist.md) software suffering from many not-so-nice features such as [bloat](bloat.md), [update culture](update_culture.md), [hardware discrimination](hw_discrimination.md) and centralized control.
After version 2.76 Blender started REQUIRING [OpenGL](opengl.md) 2.1 due to its "[modern](modern.md)" [EEVEE](eevee.md) renderer, deprecating old machines and giving a huge fuck you to all users with incompatible hardware (for example the users of [RYF](ryf.md) software). This new version also stopped working with the [free](free_software.md) [Nouveau](nouvea.md) driver, forcing the users to use NVidia's proprietary drivers. Blender of course doesn't at all care about this. { I've been forced to use the extremely low FPS [software](sw_rendering.md) GL version of Blender after 2.8. ~drummyfish } After version 2.76 Blender started REQUIRING [OpenGL](opengl.md) 2.1 due to its "[modern](modern.md)" [EEVEE](eevee.md) renderer, deprecating old machines and giving a huge fuck you to all users with incompatible hardware (for example the users of [RYF](ryf.md) laptops). This new version also stopped working with the [free](free_software.md) [Nouveau](nouvea.md) driver, forcing the users to use NVidia's proprietary drivers. Blender of course doesn't at all care about this. { I've been forced to use the extremely low FPS [software](sw_rendering.md) GL version of Blender after 2.8. ~drummyfish }
**Are there good alternatives to Blender?** Some programs to check out are [wings3d](wings3d.md), [k3d](k3d.md), [meshlab](meshlab.md) and [mm3d](mm3d.md) (looks like bloat), also for some things possibly [FreeCAD](freecad.md). Remember you can also make models manually :-) Formats like obj can be hand-written. **Are there good alternatives to Blender?** Some programs to check out are [wings3d](wings3d.md) (seems like the best candidate), [k3d](k3d.md), [meshlab](meshlab.md) and [mm3d](mm3d.md) (looks like bloat), also for some things possibly [FreeCAD](freecad.md). Remember you can also make models manually :-) Formats like obj can be hand-written.
## See Also ## See Also

View file

@ -4,7 +4,7 @@ TODO
## Example ## Example
Let's consider a simple algorithm that tests the [Collatz conjecture](collatz_conjecture.md) (which says that applying a simple operation from any starting number over and over will always lead to number 1). The algorithm in [C](c.md) would look as follows: Let's consider a simple algorithm that tests the [Collatz conjecture](collatz_conjecture.md) (which says that applying a simple operation from any starting number over and over will always lead to number 1). The program reads a number (one digit for simplicity) and then prints the sequence until reaching the final number 1. The algorithm in [C](c.md) would look as follows:
``` ```
// Collatz conjecture // Collatz conjecture
@ -35,7 +35,88 @@ int main(void)
} }
``` ```
The program reads a number (one digit for simplicity) and then prints the sequence until reaching the final number 1. Now let's rewrite the same algorithm in [comun](comun.md), a language which will allow us to produce bytecode: C will be normally compiled to [machine code](machine_code.md), however we can take a look at some immediate representation bytecode that compilers internally use to generate the machine code. The following is [LLVM](llvm.md), a widely used bytecode that can be produced from the above C code with [clang](clang.md) compiler (e.g. as `clang -cc1 tmp.c -S -emit-llvm -o -`):
```
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
; Function Attrs: noinline nounwind optnone
define i32 @next(i32 %n) #0 {
entry:
%n.addr = alloca i32, align 4
store i32 %n, i32* %n.addr, align 4
%0 = load i32, i32* %n.addr, align 4
%rem = srem i32 %0, 2
%tobool = icmp ne i32 %rem, 0
br i1 %tobool, label %cond.true, label %cond.false
cond.true: ; preds = %entry
%1 = load i32, i32* %n.addr, align 4
%mul = mul nsw i32 3, %1
%add = add nsw i32 %mul, 1
br label %cond.end
cond.false: ; preds = %entry
%2 = load i32, i32* %n.addr, align 4
%div = sdiv i32 %2, 2
br label %cond.end
cond.end: ; preds = %cond.false, %cond.true
%cond = phi i32 [ %add, %cond.true ], [ %div, %cond.false ]
ret i32 %cond
}
; Function Attrs: noinline nounwind optnone
define i32 @main() #0 {
entry:
%retval = alloca i32, align 4
%n = alloca i32, align 4
store i32 0, i32* %retval, align 4
%call = call i32 (...) @getchar()
%sub = sub nsw i32 %call, 48
store i32 %sub, i32* %n, align 4
br label %while.body
while.body: ; preds = %entry, %if.end
%0 = load i32, i32* %n, align 4
%call1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %0)
%1 = load i32, i32* %n, align 4
%cmp = icmp eq i32 %1, 1
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %while.body
br label %while.end
if.end: ; preds = %while.body
%2 = load i32, i32* %n, align 4
%call2 = call i32 @next(i32 %2)
store i32 %call2, i32* %n, align 4
br label %while.body
while.end: ; preds = %if.then
ret i32 0
}
declare i32 @getchar(...) #1
declare i32 @printf(i8*, ...) #1
attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 7.0.1-8+deb10u2 (tags/RELEASE_701/final)"}
```
TODO: analyze the above
Now let's rewrite the same algorithm in [comun](comun.md), a different language which will allow us to produce another kind of bytecode (obtained with `comun -T program.cmn`):
``` ```
# Collatz conjecture # Collatz conjecture
@ -65,7 +146,7 @@ next:
. .
``` ```
Here is annotated bytecode this compiles to: Here is annotated comun bytecode this compiles to:
``` ```
000000: DES 00 0111 # func \ next: 000000: DES 00 0111 # func \ next:
@ -128,3 +209,69 @@ Here is annotated bytecode this compiles to:
``` ```
TODO: analyze the above, show other bytecodes (python, java, ...) TODO: analyze the above, show other bytecodes (python, java, ...)
Let's try the same in [Python](python.md). The code we'll examine will look like this:
```
# Collatz conjecture
def next(n):
return 3 * n + 1 if n % 2 != 0 else n / 2
n = ord(raw_input()[0]) - ord('0')
while True:
print(n)
if n == 1:
break
n = next(n)
```
And the bytecode we get (e.g. with `python -m dis program.py`):
```
3 0 LOAD_CONST 0 (<code object next at ...)
3 MAKE_FUNCTION 0
6 STORE_NAME 0 (next)
6 9 LOAD_NAME 1 (ord)
12 LOAD_NAME 2 (raw_input)
15 CALL_FUNCTION 0
18 LOAD_CONST 1 (0)
21 BINARY_SUBSCR
22 CALL_FUNCTION 1
25 LOAD_NAME 1 (ord)
28 LOAD_CONST 2 ('0')
31 CALL_FUNCTION 1
34 BINARY_SUBTRACT
35 STORE_NAME 3 (n)
8 38 SETUP_LOOP 43 (to 84)
>> 41 LOAD_NAME 4 (True)
44 POP_JUMP_IF_FALSE 83
9 47 LOAD_NAME 3 (n)
50 PRINT_ITEM
51 PRINT_NEWLINE
11 52 LOAD_NAME 3 (n)
55 LOAD_CONST 3 (1)
58 COMPARE_OP 2 (==)
61 POP_JUMP_IF_FALSE 68
12 64 BREAK_LOOP
65 JUMP_FORWARD 0 (to 68)
14 >> 68 LOAD_NAME 0 (next)
71 LOAD_NAME 3 (n)
74 CALL_FUNCTION 1
77 STORE_NAME 3 (n)
80 JUMP_ABSOLUTE 41
>> 83 POP_BLOCK
>> 84 LOAD_CONST 4 (None)
87 RETURN_VALUE
```
TODO: make sense of it and analyze it

15
c.md
View file

@ -8,6 +8,8 @@ C is an [old](old.md) [low level](low_level.md) structured [statically typed](st
It is usually not considered an easy language to learn because of its low level nature: it requires good understanding of how a [computer](computer.md) actually works and doesn't prevent the programmer from shooting himself in the foot. Programmer is given full control (and therefore responsibility). There are things considered "tricky" which one must be aware of, such as undefined behavior of certain operators and raw pointers. This is what can discourage a lot of modern "coding monkeys" from choosing C, but it's also what inevitably allows such great performance -- undefined behavior allows the compiler to choose the most efficient implementation. On the other hand, C as a language is pretty simple without [modern](modern.md) bullshit concepts such as [OOP](oop.md), it is not as much hard to learn but rather hard to master, as any other true art. It is usually not considered an easy language to learn because of its low level nature: it requires good understanding of how a [computer](computer.md) actually works and doesn't prevent the programmer from shooting himself in the foot. Programmer is given full control (and therefore responsibility). There are things considered "tricky" which one must be aware of, such as undefined behavior of certain operators and raw pointers. This is what can discourage a lot of modern "coding monkeys" from choosing C, but it's also what inevitably allows such great performance -- undefined behavior allows the compiler to choose the most efficient implementation. On the other hand, C as a language is pretty simple without [modern](modern.md) bullshit concepts such as [OOP](oop.md), it is not as much hard to learn but rather hard to master, as any other true art.
{ Though C is almost always compiled, there have appeared some C interpreters. ~drummyfish }
C is said to be a **"[portable](portability.md) [assembly](assembly.md)"** because of its low level nature, great performance etc. -- though C is structured (has control structures such as branches and loops) and can be used in a relatively high level manner, it is also possible to write assembly-like code that operates directly with bytes in memory through [pointers](pointer.md) without many safety mechanisms, so C is often used for writing things like hardware [drivers](driver.md). On the other hand some restrain from likening C to assembly because C compilers still perform many transformations of the code and what you write is not necessarily always what you get. C is said to be a **"[portable](portability.md) [assembly](assembly.md)"** because of its low level nature, great performance etc. -- though C is structured (has control structures such as branches and loops) and can be used in a relatively high level manner, it is also possible to write assembly-like code that operates directly with bytes in memory through [pointers](pointer.md) without many safety mechanisms, so C is often used for writing things like hardware [drivers](driver.md). On the other hand some restrain from likening C to assembly because C compilers still perform many transformations of the code and what you write is not necessarily always what you get.
Mainstream consensus acknowledges that C is among the best languages for writing low level code and code that requires performance, such as [operating systems](operating_system.md), [drivers](driver.md) or [games](game.md). Even scientific libraries with normie-language interfaces -- e.g. various [machine learning](machine_learning.md) [Python](python.md) libraries -- usually have the performance critical core written in [C](c.md). Normies will tell you that for things outside this scope C is not a good language, with which we disagree -- [we](lrs.md) recommend using C for basically everything that's supposed to last, i.e. if you want to write a good website, you should write it in C etc. Mainstream consensus acknowledges that C is among the best languages for writing low level code and code that requires performance, such as [operating systems](operating_system.md), [drivers](driver.md) or [games](game.md). Even scientific libraries with normie-language interfaces -- e.g. various [machine learning](machine_learning.md) [Python](python.md) libraries -- usually have the performance critical core written in [C](c.md). Normies will tell you that for things outside this scope C is not a good language, with which we disagree -- [we](lrs.md) recommend using C for basically everything that's supposed to last, i.e. if you want to write a good website, you should write it in C etc.
@ -40,22 +42,23 @@ The standards of C99 and older are considered pretty [future-proof](future_proof
## Compilers ## Compilers
- [gcc](gcc.md): the main "big name" that can compile all kinds of languages including C, used by default in many places, very [bloated](bloat.md) - [gcc](gcc.md): The main "big name" that can compile all kinds of languages including C, used by default in many places, very [bloated](bloat.md) and can take long to compile big programs, but is pretty good at [optimizing](optimization.md) the code and generating fast code. Also has number of frontends and can compile for many platforms. Uses GENERIC/GIMPLE [intermediate representation](intermediate_representation.md).
- [clang](clang.md): another big bloated compiler, kind of competes with gcc - [clang](clang.md): Another big bloated compiler, kind of competes with gcc, is similarly good at optimization etc. Uses [LLVM](llvm.md) intermediate representation.
- [tcc](tcc.md): tiny C compiler, [suckless](suckless.md), cannot optimize as well as the big compilers but is pretty elegant - [tcc](tcc.md): Tiny C compiler, [suckless](suckless.md), orders of magnitude smaller (currently around 25 KLOC) and simpler than gcc and clang, cannot optimize nearly as well as the big compilers so the generated executables can be a bit slower and bigger, however besides its internal simplicity there are many advantages, mainly e.g. fast compilation (claims to be 9 times faster than gcc) and small tcc executable (about 100 kB). Seems to only support x86.
- [scc](scc.md): another small/suckless C compiler - [scc](scc.md): Another small/suckless C compiler, currently about 30 KLOC.
- [8c](8c.md), [8cc](8cc.md) - [8c](8c.md), [8cc](8cc.md)
- ... - ...
## Standard Library ## Standard Library
Besides the pure C language the C standard specifies a set of [libraries](library.md) that have to come with a standard-compliant C implementation -- so called standard library. This includes e.g. the *stdio* library for performing standard [input/output](io.md) (reading/writing to/from screen/files) or the *math* library for mathematical functions. It is usually relatively okay to use these libraries as they are required by the standard to exist so the [dependency](dependency.md) they create is not as dangerous, however many C implementations aren't completely compliant with the standard and may come without the standard library. So for sake of [portability](portability.md) it is best if you can avoid using standard library. Besides the pure C language the C standard specifies a set of [libraries](library.md) that have to come with a standard-compliant C implementation -- so called standard library. This includes e.g. the *stdio* library for performing standard [input/output](io.md) (reading/writing to/from screen/files) or the *math* library for mathematical functions. It is usually relatively okay to use these libraries as they are required by the standard to exist so the [dependency](dependency.md) they create is not as dangerous, however many C implementations aren't completely compliant with the standard and may come without the standard library. Also many stdlib implementations suck or you just can't be sure what the implementation will prefer (size? speed?) etc. So for sake of [portability](portability.md) it is best if you can avoid using standard library.
The standard library (libc) is a subject of live debate because while its interface and behavior are given by the C standard, its implementation is a matter of each compiler; since the standard library is so commonly used, we should take great care in assuring it's extremely well written. As you probably guessed, the popular implementations ([glibc](glibc.md) et al) are [bloat](bloat.md). Better alternatives thankfully exist, such as: The standard library (libc) is a subject of live debate because while its interface and behavior are given by the C standard, its implementation is a matter of each compiler; since the standard library is so commonly used, we should take great care in assuring it's extremely well written, however we ALWAYS have to choose our priorities and make tradeoffs, there just mathematically CANNOT be an ultimate implementation that will be all extremely fast and extremely memory efficient and extremely portable and extremely small. So choosing your C environment usually comprises of choosing the C compiler and the stdlib implementation. As you probably guessed, the popular implementations ([glibc](glibc.md) et al) are [bloat](bloat.md) and also often just [shit](shit.md). Better alternatives thankfully exist, such as:
- [musl](musl.md) - [musl](musl.md)
- [uclibc](uclibc.md) - [uclibc](uclibc.md)
- [not using](dependency.md) the standard library :) - [not using](dependency.md) the standard library :)
- ...
## Bad Things About C ## Bad Things About C

View file

@ -1,15 +1,19 @@
# Forth # Forth
Forth is a very good [minimalist](minimalism.md) [stack](stack.md)-based untyped [programming language](programming_language.md) that uses [postfix](notation.md) (reverse Polish) notation. It is yet much simpler than [C](c.md), it's very [elegant](elegant.md) and its compiler/interpreter can be made very easily, giving it high practical freedom (i.e. not being practically controlled by any central organization); it is used e.g. in space technology and embedded systems as a way to write efficient [low level](low_level.md) programs that are, unlike those written in [assembly](assembly.md), [portable](portability.md) (there even exist computers directly running Forth in hardware). Forth was the main influence for [Comun](comun.md), the [LRS](lrs.md) language. Forth ("fourth generation" shortened to four characters due to technical limitations) is a very good [minimalist](minimalism.md) [stack](stack.md)-based untyped [programming language](programming_language.md) that uses [postfix](notation.md) (reverse Polish) notation. Its vanilla form is yet much simpler than [C](c.md), it's very [elegant](elegant.md) and its compiler/interpreter can be made very easily, giving it high practical freedom (i.e. not being practically controlled by any central organization); it is used e.g. in space technology and [embedded](embedded.md) systems as a way to write efficient [low level](low_level.md) programs that are, unlike those written in [assembly](assembly.md), [portable](portability.md) (fun fact: there even exist computers directly running Forth in hardware). Forth was the main influence for [Comun](comun.md), the [LRS](lrs.md) programming language. In its minimalism Forth competes a bit with [Lisp](lisp.md).
{ It's kinda like usable [brainfuck](brainfuck.md). ~drummyfish } { It's kinda like usable [brainfuck](brainfuck.md). Also there used to be a nice Forth wiki at wiki.forthfreak.net, now it has to be accessed via archive as it's dead. ~drummyfish }
It is usually presented as [interpreted](interpreter.md) language but may as well be [compiled](compiler.md), in fact it maps pretty nicely to [assembly](assembly.md). { There is also some discussion about how low level Forth really is, if it really is a language or something like a "metalanguage", or an "environment" to create your own language by defining your own words. Now this is not a place to go very deep on this but kind of a sum up may be this: Forth in its base version is very low level, however it's very extensible and many extend it to some kind of much higher level language, hence the debates. ~drummyfish }
There are several Forth standards, most notably ANSI Forth from 1994 (the document is [proprietary](proprietary.md), sharing is allowed, 640 kB as txt). It is usually presented as [interpreted](interpreter.md) language but may as well be [compiled](compiler.md), in fact it maps pretty nicely to [assembly](assembly.md). Even if interpreted, it can still be very fast. Forth systems traditionally include not just a compiler/interpreter but also an **interactive environment**, kind of [REPL](repl.md) language shell.
There are several Forth standards, most notably ANSI Forth from 1994 (the document is [proprietary](proprietary.md), sharing is allowed, 640 kB as txt). Besides others it also allows Forth to include optional [floating point](float.md) support.
A [free](free_software.md) implementation is e.g. GNU Forth ([gforth](gforth.md)) or [pforth](pforth.md) (a possibly better option by LRS standards, favors [portability](portability.md) over performance). A [free](free_software.md) implementation is e.g. GNU Forth ([gforth](gforth.md)) or [pforth](pforth.md) (a possibly better option by LRS standards, favors [portability](portability.md) over performance).
Forth was invented by Charles Moore in 1968, for programming radio telescopes.
## Language ## Language
Forth is case-insensitive (this may however not be the case in some implementations). Forth is case-insensitive (this may however not be the case in some implementations).

View file

@ -3,7 +3,7 @@
This is an auto-generated article holding stats about this wiki. This is an auto-generated article holding stats about this wiki.
- number of articles: 526 - number of articles: 526
- total size of all texts in bytes: 2616667 - total size of all texts in bytes: 2619403
longest articles: longest articles:
@ -23,6 +23,17 @@ longest articles:
latest changes: latest changes:
``` ```
Date: Thu Dec 21 12:04:09 2023 +0100
assembly.md
blender.md
devuan.md
fascism.md
forth.md
fun.md
gemini.md
needed.md
programming_language.md
wiki_stats.md
Date: Wed Dec 20 20:17:45 2023 +0100 Date: Wed Dec 20 20:17:45 2023 +0100
fascism.md fascism.md
feminism.md feminism.md
@ -42,13 +53,5 @@ linux.md
public_domain.md public_domain.md
sin.md sin.md
wiki_stats.md wiki_stats.md
Date: Mon Dec 18 08:32:56 2023 +0100
lrs.md
prime.md
public_domain.md
wiki_stats.md
Date: Mon Dec 18 08:02:57 2023 +0100
approximation.md
bloat.md
``` ```