(Modern) C Programming Tips and Tricks


#82

Do you have any interest in Dart? It’s a dream to work with, and it compiles down to Javascript, so it’s portable.

Edit: to stay on topic, I used function pointers the other day. They’re great for reducing copious condition checking when deciding what to do:

log_position_t *(*seek)();
if (catting)
    seek = log_seek;
else 
    seek = log_seek_next;

The remainder of the function body is nice and clean as a result, saving 6 lines of source code.


#83

Depending on the processor there’s not much overhead in function pointers either. On some (AVR) they can be pretty slow though.


#84

Ah! A digression I can’t resist. Working on Dart is actually my day job. :blush: Glad you’re enjoying it!

Having said that, I could agree more with @jasonw22’s astonishment. Crazy how far we’ve come!


#85

In general I’m always a bit wary of feature creep in languages, sometimes I worry that Javascript (and C# which I used to code professionally) is going to end up like C++ which just consumes programming paradigms.

The one exception I would make is for discriminated unions / sum types / ADTs / etc and pattern matching. I find any language without these to be extremely hard to safely construct data models with. Although in truth it’s an incredibly hard thing to retrofit (e.g. variants in C++17).

I do think there is an opening for a lighter programming language (e.g. like Python or Javascript) to be based around them. At the moment your main choices are either:

  • Rust: too hard and too sanctimonious
  • Haskell: just too hard

Seriously @ppqq this is what you need to do for Dart 3.0 :stuck_out_tongue_winking_eye:


As an aside about Javascript, I find it incredibly hard to separate the language from the ecosystem. The ecosystem just moves too fast for me. I remember helping my wife out with her PhD about 10 years ago, parts of it used Python and NumPy. That knowledge is still relevant and useful today, likewise much of the Python ecosystem. Given it’s ubiquity it would be wonderful for Javscript to also end up in a similar place.


#86

Have you checked out elm? I haven’t used it in earnest yet but a few friends of mine have completed some web projects with it. Seems promising, though there are still a few things to work out…


#87

I never really understood why Python has always been able to achieve such admirable stability. I do understand JavaScript’s chaos, though. Its ubiquity and its use as a UI language primarily mean that it has very frequent encounters with the mess of the real world and it does not emerge unscathed. Would be fantastic if it settled down someday, but I’m not anticipating it to happen anytime soon as user interactions are still rapidly evolving (and I suspect this is simply the nature of UI).

Apologies for straying off-topic. But if you squint, JavaScript kinda looks like C sometimes!


#88

To play devil’s advocate, I still see issues pop up about Python 2.x vs. 3.x sometimes. JS and the whole transpiation idea for being able to use new language features (ES6/ES7+), while being portable across environments (i.e. code is transpiled to ES5) is pretty cool.

That being said, as someone who works with JS full time (and specifically a large AngularJS 1.x app), it can definitely get overwhelming. At the current moment, it seems like building a larger, modern web app that adheres to best practices involves understanding and using different things for the view layer (React/Vue/Angular 2), CSS-in-js (styled-components, glamour, etc.), the data layer (Redux), adding in strongly-typed benefits (TypeScript), immutable data structures (Immutable.js), and then building/bundling/packaging everything (Webpack, NPM, Grunt, Gulp, etc.).

I tried to sit down and start looking at what a rewrite of our angular app would look like with a collection of these newer technologies, and it was very overwhelming…this is part of the reason why I’ve been against adding dependencies in the side projects I’ve worked on, including the teletype docs enhancements :grin:


#89

I am aware of it, and have heard good things about it too, I just don’t do any web dev anymore. I do think the Haskell/ML style of separating the type signature from the function implementation to greatly aid readability. C style function declaration does not cope well with the templates and traits that C++ and Rust respectively add into the mix.

I think the environments that it’s used in don’t have the same “not invented here” ethos. I suspect due to a lack of resources more than anything. The only unicorn that comes to mind that uses it is Dropbox. From the outside, it seems that some of the churn of Javascript comes from engineers needing to make busywork. Javascript is a victim of it’s own success.

That is a fair point. The pain point was always the redefinition of the string type to be an opaque Unicode text type, rather than a byte array. You see the same issue in a lot of other pre-Uniciode languages (Haskell has 3 common string types in use, String, Text and ByteString, yuck!). I suspect history will prove them correct in making the change, but that they could have made the transition easier.

To anyone on the fence, 3.6 has enough interesting new features over 2.7 that it makes the change worthwhile. I particularly like formatting strings, and pathlib from 3.4 is really nice too.

That is a very wise decision.

A few years back I decided I want to make a printable picture-coded calendar for my pre-school daughter. It would list the days she was at nursery, weekends, birthdays, what her new Mr. Men / Little Miss Book was this week, etc. It’s been incredibly useful, particularly with understanding the concept of days and weeks.

I very briefly thought about doing it in Haskell or some such, but the main point was to get it done relatively quickly, and well, HTML/CSS/JS is an amazing canvas for creating data driven documents. I used React to do it (none of other stuff like Redux), partly to learn what is was all about as it was generating a lot of hot air at the time. Plus it also used Babel as vanilla Javascript is yucky.

I was really impressed by it. It made it really easy to quickly build small composable bits of UI. Until 6 months later when I tried updating my package.json, then it all went to crap. So now it’s stuck using 2 year old versions of everything. I do worry what I’d do if I were doing this professionally, running old dependencies is a great way to get Equifaxed.


#90

Just a little aside - I’ve been writing Haskell (casually) for the last 3 months & once you realize that you don’t need to understand monads & functors to get in the door it’s actually pretty accessible, albeit with a somewhat different mental model of data & control flow. Pattern matching, ADTs and list comprehensions are sorely missed when I’m writing C day-to-day. These 3 things are much closer to the way I think about software, than the traditional imperative approach.

Now if only it would run on a microcontroller, I wouldn’t be compelled to partake in this thread!


#91

I guess I was a being a bit tongue in cheek. I also write Haskell a fair bit these days too, I started learning about 2 years ago (2nd attempt). It’s now my go to programming language. I even understand what a Monad is!

I’m just saying that there is an opening for a less full-on language that also brings pattern matching and ADTs, etc. All new programming languages should include them, and as you say they behave much closer to how we think about software.

No microcontrollers… but there is CλaSH which compiles down to Verilog/VHDL. I’m not sure how mature it is, and in truth it’s really a DSL embedded in Haskell, with it’s own set of idioms.

Rust is definitely getting close to being practical with embedded hardware, and has a lot of stuff from Haskell. (Traits in Rust are like Typeclasses in Haskell.)

I also completely forgot about Swift, which may end up gaining popularity outside of the Apple ecosystem. I’m don’t know much about it, and have no idea how approachable it is as a language.


#92

Swift is pretty easy to learn. And this coming from a guy that doesn’t know how to use a monad. :wink: no idea what non-apple use of swift is like though.


#93

while we’re derailing the C programming tips thread, i guess i should reveal that the next monome thing heavily uses lua.


Approaching: norns
#94

You’ve probably used them more than you know. If you have a value wrapped inside of something, e.g. an optional in Swift. Then when you bind1 the inner value into a new value (via some computation). That’s a amore^H^H^H^H^H, I mean, that’s monadic.

A bit of Googling tells me that Swift has a null-coalescing operator (??), which is basically a monadic bind.

1 sometimes also called flatMap

Ooooo interesting. Never really used Lua. I do know it uses 1-based indexing, which will make the mathematicians happy.


#95

you cant do that to us b

(I’m saying that tongue fully in cheek…this is great news!)


#96

oh hello (20 characters for You Had Me At Lua)


#97

And here I’ve been studiously avoiding derailing the C programming tips thread with C++ tips.


#98

I got into it a tiny bit - kind of interesting & fun! I paired it with an icestick fpga, open-source yosys toolchain, & a ‘usbstreamer’ usb->i2s soundcard. Got some basic stuff working like an attack-decay envelope follower. The really wicked feature of clash for fixed-point DSP design is the fixed-point fractional type system.

I would argue audio domain is not well-suited to the ‘pure hardware’ approach. If you ‘directly’ synthesize a moderately complex DSP algorithm in hardware, physical size (number of gates) gets huge rather rapidly. So you quickly end up running out of gates if your logic is clocked directly at a typical audio samplerate.

Say you have like 10 biquad filters in your algorithm, you have to choose between either:
a) using 10 x as many gates
b) designing aux logic which shovels biquad state for a single ‘biquad accelerator’ to & fro a RAM several times per audio frame.

Even straightforward algorithms can get pretty hairy when you play this game. Something more involved/conceptual like lines/waves!? zoinks!

It would be so cool if we could somehow use clash’s fractional types to write blackfin-optimised fixed-point DSP objects for aleph! Even after much practice, moving floating point ideas to fixed-point blackfin-ised C is laborious…


#99

I know nothing about FPGAs. But I’m okay with Haskell…

The above strikes me as the kind of thing that one can generalise in Haskell…

ramBacked :: (KnownNat n, RamStorable d, RamState d s)
          => (Signal a -> s d (Signal b))  -- the signal you wish to multiplex, has access to the state-like monad RamState to store and retrieve contents
          -> Signal (Vec n a)
          -> Signal (Vec n b)

The above is really rough, as it’s based on a very quick parsing of the types that Clash uses. And I haven’t made any attempt to deal with clock rates in the type signatures.

I also don’t know if Clash is able to deal with Signals that operate internally at a faster rate.


#100

I saw an article on HackerNews today about Lua. It was interesting learning about the whole PUC Lua vs LuaJIT thing. And also 5.1 vs 5.2 vs 5.3.

So… which version of Lua?


#101

wow this thread has drifted pretty far :smiley:

been using 5.3 but i’m thinking of dialing back to 5.2 and freezing there, so as to allow switch to luaJIT

which sucks cause i like that 5.3 gives us Integers, finally… but in another project i saw 20x - 100x speedups with luaJIT vs PUC lua. hard to argue with that.