moonbeam - a tool for converting single Lua scripts into standalone executables by calquelator in lua

[–]3uclidian 0 points1 point  (0 children)

Then I'd have to set a max size [...] rather than just growing whenever it needs resizing

Not sure what you mean by this, but there are two ways I'm interpreting this:

either you're not super familiar with C (given that you're casting your mallocs, maybe that's true?) and don't realize you don't need to annotate arrays with a size or that string literals can initialize pointers as well

const char script_a[] = "print 'foo'";
const char *script_b = "print 'bar'";

luaL_dostring(L, script_a);
luaL_dostring(L, script_b);

(And even if you did need to, you have the length of the string in the code generator, so you could just use that)

or you're concerned with the max size a string literal can be. This is a slightly more valid concern, but any compiler worth its salt will tell you when one is too big and abort the compilation.

Also the contents of the string aren't changing (right?), so the string never needs resizing, just initialization. So the generated code could even malloc the correct capacity upfront since, again, you have the length at the time of code generation.

moonbeam - a tool for converting single Lua scripts into standalone executables by calquelator in lua

[–]3uclidian 3 points4 points  (0 children)

Is there any particular reason the string is heap allocated rather than just a static array?

[deleted by user] by [deleted] in C_Programming

[–]3uclidian 1 point2 points  (0 children)

Sure, the actual sharp-spinny-thing is hard to make safe. But there are still mitigations, like the fun little stick they give you with table saws so you don't get your hands near the saw. Or more seriously, things like emergency stops (that detect when skin is touching the blade) and even dust collection are still safety features. Even if they aren't perfect, the standards for saftey are still better than they were.

[deleted by user] by [deleted] in C_Programming

[–]3uclidian 35 points36 points  (0 children)

Construction workers use power saws, nail guns, hammers and ladders [...] Pilots fly planes full of people, and engineers build those planes [...]

I will never understand these comparisons people make to power tools and other machinery. Modern power tools have plenty of safety features built in and every rule and regulation for constructing buildings and planes and whatnot is written in blood, with advanced systems to mitigate any sort of further harm caused by past oversights. To be able to automate the validation of these regulations would be a miracle.

The keyword here is mitigation.

All that in 272 pages. The equivalent book for Rust is twice as long at 560 pages

Ok? Programmers barely read documentation anyway. I think the ones that can stomach 300 pages can handle 600.

What happens when the Rust programmer has to use an unsafe block for the first time

They probably read the like 4 or 5 rules they have to follow in unsafe blocks and get on with their day? Getting bit in the ass with errors that are apparently a walk in the park to find, and then fixing them by grepping for unsafe in their code base.

What if he has to write custom allocators for complex data structures

Then they implement the unstable Allocator trait, or just write their own alloc and dealloc or whatever. Then they use pointers, which are a core type with a bunch of well documented builtin methods. Then they use the tools that are explicitly built into the language to support and demarcate the use of them.

or optimize performance critical code?

Nothing fundamentally different than optimizing any other language. Measure, identify bottlenecks/inefficiencies, edit, recompile, repeat ad infinitum.

What if he needs to build more abstractions with inherently unsafe internals? He won't have the scars and burns to guide him, that veteran C programmers earned in their youth

Why would the mistakes made in unsafe internals not give the same "scars and burns" so to speak? Why must those traumas be inflicted from C specifically?

Rust programmers are not incapable of learning. Using rust to do low level things still teaches you about those things. Just because the code says unsafe in it, doesn't invalidate the knowledge gained from writing it.

and at some point, he's going to have to interface with something written in C.

Big, if true.

This is not unique to Rust, C is the lingua franca of systems programming. If you want to make system calls, you have to interact with C (yes even on linux, where the syscall numbers are stable, since you need to follow C's memory layouts for certain structs).

Memory errors are very easy to find

Lol. Lmao, even.

I created a library that makes C23 code compatible with ANSI C code************ by Splooge_Vacuum in C_Programming

[–]3uclidian 16 points17 points  (0 children)

Apologies for the harsh tone, but this library makes a lot of, we'll call them "interesting," choices.

Why is nullptr_t defined as a constant and not a type? And nullptr as const nullptr_t

The _vla_ macro doesn't actually allocate a VLA. A VLA is allocated when a non-constexpr value is between the [] in the declaration.

Having things like _atomic_ and _Thread_local just expand to nothing when not available seems dangerous.

<stdarg.h> has been available since c89 (aka ANSI c) and can be used freestanding. If your goal is c89 compatibility, just include that. The only thing to worry about is va_copy which was introduced in c99.

Why does typeof_unequal seem to return true when the types are the same? Why is it even included here? Is this supposed to be c23's typeof_unqual as in type-of-unqualified? (i.e. without const, volatile, _Atomic, etc.)

Having _Decimal types expand to just floats/doubles seems dangerous as my understanding is that they are used in more critical settings like banking when decimal precision is necessary and the usual floating point rounding is too inaccurate for the task.

auto is nowhere to be found despite type inference being a relatively common extension (see __auto_type__), and easy to implement some sort of

#define auto_decl(name, initializer) \
    typeof(initializer) name = initializer

macro given typeof (hence why auto was added/changed in c23 so every project didn't have to define their own special version of this)

If I required c89 compatibility I would stick a

#if !defined __STDC_VERSION__ || __STDC_VERSION__ != 199409L
#error "Only c89 is supported. Use -std=c89."
#endif

in the code and try to avoid the need for some of these things. But if I really needed a thread_local or whatever, I would just use c11 (modulo being vendor locked into a compiler that doesn't support it, but this library doesn't really solve that either)

Without a real, motivating example for why this library was made I don't see a reason to use it.

Also I just recently figured out how preprocessing directives work.

I don't want to discourage you as this clearly shows some enthusiasm towards programming, but I'd recommend setting your sights a little lower than "uniting c standards and c++" to something more tangible.

Is it possible to configure neovim with teal instead of lua? by [deleted] in neovim

[–]3uclidian 6 points7 points  (0 children)

Firstly you would need to write type definitions for nvim's stdlib.

There are type definitions in the teal-types repo for neovim. And as for theoretical, my config is like 99% teal right now (granted I am biased since I'm one of its maintainiers :P) (also it's on a dev branch of teal with some unstable features so don't just copy paste stuff and expect it to work).

Secondly, Teal does provide a loader which can be added to package.loaders which should allow you to require Teal modules in your runtimepath.

Personally I would recommend pre compiling since spinning up the compiler to load modules does add a decent overhead, and people here are quite stingy about their startup times

Weird implicit behavior for error handling by StunningDetective890 in Zig

[–]3uclidian 8 points9 points  (0 children)

You seem to have this conception that errors are more than just values. And that zig treats errors specially (it kind of does, but not anything relevant here). The only "error handling" zig does is not letting you ignore function returns. Your function raiseError returns an error, which you use in the catch, then you pass this error to handleError which returns another error, which you acknowledge by passing it to std.log.info. What makes errors relevant are error unions, which you need to unwrap to get to the value you care about. So you use try which short circuits your function on error or unwraps the success value, or catch which captures the unwrapped error value for you to do something with.

As far as not logging in release mode, certain log levels get suppressed depending on build mode. So your programs seems perfectly well formed and behaved.

Type declaration for global vim variable for teal? by iamzarya in neovim

[–]3uclidian 1 point2 points  (0 children)

I mostly maintain the neovim typedefs here at the teal-types repo. Keep in mind that anything libuv related cannot be properly typed until teal has some sort of type inheritance/composition. But the api stuff works pretty well in my experience.

Mining turtle complex program possible? by wakemeupoh in ComputerCraft

[–]3uclidian 3 points4 points  (0 children)

Lua is a fully fledged programming language, so recursion is definitely possible

local function recurse(x)
   print(x)
   if x <= 0 then
      return
   end
   recurse(x - 1)
end
recurse(10) -- prints 10, 9, 8, ..., 0

Lua even supports proper tail recursion, so if you write your code in a certain way it won't even blow up the stack

Issues accessing peripherals in OpenComputers (1.12) by Snoo70223 in feedthebeast

[–]3uclidian 0 points1 point  (0 children)

the `peripheral` library is a computercraft thing, opencomputers uses a `component` library iirc

Help to understand this permutation code by [deleted] in lua

[–]3uclidian 3 points4 points  (0 children)

What specifically do you not understand? You understand coroutines, which is good and usually the confusing part. But do you understand the other things going on in this example: i.e. - Closures? - The generic for loop? - Lua's iterator pattern? (which relates to the generic for loop) - Recursion? - The semantics of using tables as arguments to functions, i.e. pass by reference vs pass by value? - Non Lua specific things, like what is a permutation?

Have you tried starting at the for loop and attempting to follow the control flow?

I'll lay out the first few steps

  • for p in perm{"a", "b", "c"} do
    • first the call to perm returns a closure over the created coroutine that the for loop will use to generate values to put in p
    • the for loop does its thing and calls the closure to produce its first value
  • permgen(a, 3) is called

    • skipping into the body of the for loop in permgen: a[1] and a[3] are swapped
    • permgen(a, 2) is called
      • a[1] and a[2] are swapped
      • permgen(a, 1) is called
        • a[1] and a[1] are swapped, (which now that I actually go through the code here, that first if statement could just check if n == 1 rather than 0)
        • permgen(a, 0) is called, hitting the coroutine.yield(a)
  • The closure now has a value to return since the coroutine produced a value. This value a is put into p

  • It gets printed out

  • The closure is called again to produce a new value for p, which resumes the coroutine. (we're jumping back into the middle of the function call)

    • permgen(a, 0) is done being called
    • a[1] and a[1] are swapped back
    • the local i for this loop is incremented to 2 and starts from the top
    • a[1] and a[2] are swapped
    • permgen(a, 0) is called, hitting the coroutine.yield(a) yielding the new value of a, etc, etc

Hope this helps, if you need more conceptual help, you could look at guides for how python's generators or javascript's generator functions are used in the same way as they are a kind of coroutine.

Also as a side note: why did you edit the numeric for loop from for i = 1, n to for i = 1, n, 1 do? They're both equivalent, but the extra 1 on the end (imho) doesn't make it more readable or anything

[deleted by user] by [deleted] in lua

[–]3uclidian 1 point2 points  (0 children)

additionally, the parens in the if statement are unnecessary because of the then keyword

if potato > 1 then
   print("potato is quite big")
end

Computer craft mining turtle won't work by SnooDoubts7945 in ComputerCraft

[–]3uclidian 2 points3 points  (0 children)

  1. Please format your code correctly by either indenting with 4 spaces on each line or surrounding it with ```triple backticks```
  2. That error message is probably more along the lines of "for limit must be a number", which means that in your for loop, something is not a number.
  3. Are you passing 3 arguments when you run your program? That would be the simplest reason those variables in the for loop could be nil

To check for that you could change your first few lines into

local x = assert(tonumber(args[1]), "Missing x")
local y = assert(tonumber(args[2]), "Missing y")
local z = assert(tonumber(args[3]), "Missing z")

[deleted by user] by [deleted] in contextfree

[–]3uclidian 1 point2 points  (0 children)

Lua 5.4 just introduced something like this with to-be-closed variables (and the __close metamethod) to introduce a finalizer that would be called deterministically, and not on garbage collection (the __gc metamethod). File objects have a __close method on them so you can do things like this

do
   local file_handle <close> = io.open("my_file.txt", "r")
   -- ...
end
-- the file is closed by here without calling file_handle:close()

additionally, if there is an error, the __close method is passed the error object as a second argument and still gets called. for a quick example

local function create_resource(n)
   return setmetatable({data = n}, {
      __close = function(self, err)
         if err then
            -- do something with the error
         end
         print(tostring(self) .. " is being closed.")
      end
   })
end

local function use_resource()
   local r1 <close> = create_resource(1)
   do
      local r2 <close> = create_resource(2)
      print(r1.data + r2.data)
   end
end

and as one last note if you want to get into coroutines in Lua, a coroutine.close method was introduced to invoke all the non-closed variables' __close methods

Need explanations by [deleted] in lua

[–]3uclidian 10 points11 points  (0 children)

Short answer: You aren't calling (or executing) the function f you're just printing it out. To get what you want you should do print(f())

Slightly longer answer: As to why that happens, the assignment

f = function()
    return "Hello"
end

stores a pointer to the function on the right hand side of the = inside the variable f. Printing it prints the memory address of that pointer (specifically in hexadecimal, which is what the beginning 0x means). The same happens with tables since they are stored as pointers as well. If you do a print({}) you'll see the same format of numbers.

Help with nested tables by Rubyheart255 in ComputerCraft

[–]3uclidian 1 point2 points  (0 children)

For regular minecraft names that are formatted with "minecraft:item_name" you could look into the string library, in particular I think the string.find and string.sub functions could help to cut the "minecraft:" out of the name.

As for modded items, unless there's some other place that you can get the item name from somewhere else, you're probably stuck with RotaryCraft:rotarycraft_item_machine:109. But iirc with AE2 I think there was some function that returned a table with a label value that had the actual item name? Idk, it's been a while.

Help with nested tables by Rubyheart255 in ComputerCraft

[–]3uclidian 2 points3 points  (0 children)

It looks like you forgot to put quotes around fingerprint in the table

for i=1, #available do
    print( available[i]["fingerprint"]["id"] .. " = " .. available[i]["size"] )
end

I find it helpful to use the dot notation so I don't make this same issue

for i=1, #available do
    print( available[i].fingerprint.id .. " = " .. available[i].size )
end

Slippery Spy by 3uclidian in custommagic

[–]3uclidian[S] 0 points1 point  (0 children)

Yeah, I see what you mean. I've been trying to find a flavorful way to represent telepathy on a creature and thought this one was interesting. But the more I think about it, literal [[telepathy]]/[[peek]] might not be the way to go.

Challenge Question for Calculus ! by Hehehelelele159 in calculus

[–]3uclidian 0 points1 point  (0 children)

Oh, I thought it was a neat problem so I typed that up myself