ejolson
Posts: 4849
Joined: Tue Mar 18, 2014 11:47 am

Re: Project Digital Apocalypse Not Now

Sat Aug 03, 2019 8:00 pm

jahboater wrote:
Sat Aug 03, 2019 9:12 am
hello_world is closer to normal English and is therefore easier to read.
In my opinion, it is not practical to enforce coding standards at the language level because identical standards may not be suitable for all the different application domains that a general purpose language is meant to cover.

As just mentioned, COBOL enforced an English-like readability useful for accounting and codifying business practices while at the same time making operating systems, weather forecasting models, engineering software, web browsers and mouse interfaces difficult. The reason Algol was created for use in technical publications is because algorithms described using common English are difficult for people to understand. This is also why algebra, schematics of circuits and diagrams of molecular bonds are used in place of English words. Imagining organic chemistry would be easier to understand if all the technical notation were omitted is the same mistake as thinking a computer algorithm would be easier to understand if described using only English words.

From this point of view, the less a programming language resembles English, the more likely it is suitable for conveying complicated algorithms to the computing hardware as well as to people.
Last edited by ejolson on Sun Aug 04, 2019 2:04 am, edited 1 time in total.

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 12:37 am

Well that's a bummer. My Rust code may be "safe" but as I was experimenting with threads in Rust I managed to get my program to segfault.

Can't for the life of me find where to send Rust bug reports.
Memory in C++ is a leaky abstraction .

ejolson
Posts: 4849
Joined: Tue Mar 18, 2014 11:47 am

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 1:28 am

Heater wrote:
Sun Aug 04, 2019 12:37 am
Well that's a bummer. My Rust code may be "safe" but as I was experimenting with threads in Rust I managed to get my program to segfault.

Can't for the life of me find where to send Rust bug reports.
Is it possible to install a signal handler for SIGSEGV in Rust?

The advantage of using a popular and established programming language is that you need only examine your own code when fixing bugs. With new and emerging technologies the bug could be anywhere in the tool chain. This is not good in a first programming language designed for beginners. Maybe coding a parallel Karatsuba multiplication routine would help illustrate in what ways Rust memory safe concurrency is useful.

In regards to the insane British anagram challenge, there may be additional parallelism in the algorithm used by zanagram.c that hasn't been explored. One could still try a conversion of the existing code to Rust; however, when doing so it would be wise to remember the original program was written by the zombies with help from a dog who wishes to remain anonymous.

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 6:17 am

This fun. How many languages have we broken with our challenges so far? Do these language creators ever use their languages for anything serious?
:)

In my early experiments with threads in Rust all was going well until I started to use the spmc "crate". spmc implements a single producer, multiple consumer arrangement of threads communicating via channels:

Code: Select all

pub fn mpscBug() {
    // Create a single producer/multiple consumer channel
    let (tx, rx) = spmc::channel();

    // Store for thread handles
    let mut handles = Vec::new();

    // Create 4 threads reading the rx channel.
    for n in 0..3 {
        let rx = rx.clone();
        handles.push(thread::spawn(move || {
            let mut wordCount = 0;
            loop {
                let received = rx.recv();
                match received {
                    Ok(word) => {
                        wordCount = wordCount + 1;
                    },
                    Err(e) => {
                        println!("Reader {}: {}, ", n, wordCount);
                        break;
                    }
                }
            }
        }));
    }

    // Create 1 thread reading the dictionary file and writing words to the tx channel.
    handles.push(thread::spawn(move || {
        let file = File::open("/usr/share/dict/british-english-insane").unwrap();
        for line in BufReader::new(file).lines() {
            let word = line.unwrap();
            tx.send(word).unwrap();
        }
    }));

    // Make sure our threads are done before quitting.
    for handle in handles {
        handle.join().unwrap();
    }

    println!("Done.");
}
This crashes out with a variety of segfaults and such. Sometimes it does actually complete, with a randomized value of the word count result! :

Code: Select all

$ ./target/release/threads-rust
Segmentation fault (core dumped)

$ ./target/release/threads-rust
Reader 0: 654274,
Done.

$ ./target/release/threads-rust
free(): invalid pointer
Aborted (core dumped)

$ ./target/release/threads-rust
free(): invalid size
Aborted (core dumped)

$ ./target/release/threads-rust
Reader 0: 654272,
Done.

$ ./target/release/threads-rust
munmap_chunk(): invalid pointer
Aborted (core dumped)
With much the same result on PC or Pi.

Looks like I have to sign up to some Rust forum to find out where to report this bug.
Memory in C++ is a leaky abstraction .

jahboater
Posts: 5413
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 6:32 am

Heater wrote:
Sun Aug 04, 2019 6:17 am
Looks like I have to sign up to some Rust forum to find out where to report this bug.
Or perhaps the LLVM forum?

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 7:46 am

Ha! Maybe. Who knows.

But nah, I'm going straight to the top. Somebody there can follow that bug down the rabbit hole.
Memory in C++ is a leaky abstraction .

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 3:53 pm

So it looks like my Rust threads and channels failure is down to the spmc library I'm using (Single Producer, Multiple Consumer) which is not a standard out of the box Rust library.

spmc makes liberal use of the Rust "unsafe" keyword to bypass all those nice compile time checks. With the result that my code crashes on x86 Linux, Windows WSL, and both 32 and 64 bit Pi.

Ah, well, time for plan B.
Memory in C++ is a leaky abstraction .

ejolson
Posts: 4849
Joined: Tue Mar 18, 2014 11:47 am

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 5:41 pm

Heater wrote:
Sun Aug 04, 2019 3:53 pm
Ah, well, time for plan B.
Is plan B to use Swift, Go, C# or Kotlin?

My Pi 4B is still in the box, after waiting to get one, I don't now have time to even open the box. If the digital apocalypse doesn't happen first, next week should provide time to figure out a reasonable cooling solution and make a new bar chart of fame.

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 6:35 pm

ejolson,
Is plan B to use Swift, Go, C# or Kotlin?
Ha! What do you think I am? Some programming language flibbertigibbet? I already got enough shiny things to play with.

Besides, Swift seems like Apple's recreation of Rust. When I tried Go a few years back it ended up slower than the JS I had shunting XML streams around. C# has no reason to exist, it's just Microsoft's version of Java which itself has no reason to exist. Kotlin is dependent on the Java VM and the Java class library, blech.

Importantly none of then stand a cat in hells chance of working on simple bare metal micro-controllers so I'm not inclined to be interested.

No, plan B is good old fashioned mutexs and shared memory, like the good old days, but using Rust's standard lib.

Plan C is to resurrect my one and only attempt at a compiler years ago...
Last edited by Heater on Sun Aug 04, 2019 8:38 pm, edited 1 time in total.
Memory in C++ is a leaky abstraction .

jahboater
Posts: 5413
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 7:10 pm

ejolson wrote:
Sun Aug 04, 2019 5:41 pm
should provide time to figure out a reasonable cooling solution and make a new bar chart of fame.
I fancy one of these:
https://wickedaluminum.com/collections/ ... issipation

They were great for the old Pi1 which needed cooling even less than the Pi4 does.

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Sun Aug 04, 2019 10:41 pm

Those cases are cool. Not just literally.

Given the price of a 4GB Pi 4 one can almost justify the expense.
Memory in C++ is a leaky abstraction .

User avatar
Gavinmc42
Posts: 4363
Joined: Wed Aug 28, 2013 3:31 am

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 1:26 am

No, plan B is good old fashioned mutexs and shared memory, like the good old days, but using Rust's standard lib.

Plan C is to resurrect my one and only attempt at a compiler years ago...
I have only had a quick look at D, is that any better?
I'm dancing on Rainbows.
Raspberries are not Apples or Oranges

ejolson
Posts: 4849
Joined: Tue Mar 18, 2014 11:47 am

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 1:39 am

Gavinmc42 wrote:
Mon Aug 05, 2019 1:26 am
No, plan B is good old fashioned mutexs and shared memory, like the good old days, but using Rust's standard lib.

Plan C is to resurrect my one and only attempt at a compiler years ago...
I have only had a quick look at D, is that any better?
I think the digital apocalypse could be ended right now by a sudden barrage of D programs which check for anagrams in the insane British dictionary. However, like other languages that require garbage collectors, D may not be as suitable for bare-metal micro controllers. Different opinions are welcome.

That aluminium case for the Pi 4B certainly looks nice. Given my budget, I suspect a different solution will present itself that involves scavenging heatsinks from surplus motherboards. More details as things develop.

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 4:00 am

Boo. Rust is a terrible language, worst I ever seen, never using rust again. Stamps foot.

Why? Because after all I said about how great it was for not accepting things like "+=" it turns out that it actually does. That would be bad enough alone but it gets worse. Rust has a tool called "clippy" which is basically a linter/style checker thing, that complains my about using "a = a + 1" and suggests I use "a += 1".

Like so:

Code: Select all

$ cargo clippy
...
...
warning: manual implementation of an assign operation
  --> src/insane-british-anagram-5.rs:90:25
   |
90 |                         i = i + 1;
   |                         ^^^^^^^^^ help: replace it with: `i += 1`
...
...   
Just awful . Now I have to go though all my code and fix a hundred clippy warnings so as to keep the Rust style.
Memory in C++ is a leaky abstraction .

jahboater
Posts: 5413
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 5:42 am

ejolson wrote:
Mon Aug 05, 2019 1:39 am
That aluminium case for the Pi 4B certainly looks nice. Given my budget, I suspect a different solution will present itself that involves scavenging heatsinks from surplus motherboards. More details as things develop.
The wicked case is expensive and that level of cooling is not needed. Its kind of nice though if you don't use WiFi, the Pi is encased in a heavy machined aluminum block.

I suggest not bothering with any additional cooling at first. Leave it out of a case in free air, preferably on edge, and monitor for throttling with "vcgencmd get_throttled" after a typical workload.

User avatar
Paeryn
Posts: 2900
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 2:06 pm

Heater wrote:
Mon Aug 05, 2019 4:00 am
Boo. Rust is a terrible language, worst I ever seen, never using rust again. Stamps foot.

Why? Because after all I said about how great it was for not accepting things like "+=" it turns out that it actually does. That would be bad enough alone but it gets worse. Rust has a tool called "clippy" which is basically a linter/style checker thing, that complains my about using "a = a + 1" and suggests I use "a += 1".
...
Just awful . Now I have to go though all my code and fix a hundred clippy warnings so as to keep the Rust style.
A slight overreaction there, there's nothing wrong with having compound operation and assignments, and clippy's warning is just that, nobody forces you to follow its recommendations and you can always tell clippy to not report them with (I think)

Code: Select all

#![allow(clippy::assign_op_pattern)]
I must say, they have one ugly use of the op= which isn't an assignment, where e.g. 2..8 is a right-exclusive range like Python's (so goes from 2 to 7) there is a right-inclusive range which is 2..=8
She who travels light — forgot something.

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 3:51 pm

Paeryn,

My post was very much tongue in cheek. I hoped the "Stamps foot" part would make that clear.

I could certainly configure clippy's rules however I like. Or not use it at all. But I'm not going to do that because:

1. So far clippy has not complained about anything I'm really attached too. Or suggested anything I really object to.

2. Clippy has made a lot of good suggestions for cleaning up my code, often making it shorter and more readable. Even to the point of suggesting totally different types and language constructs. Pretty impressive.

3. I'm going to assume all the world's Rust users are using default options. Or at least everything that comes out of the Rust developers. So it makes sense to me to fall in line with that rather than go my own way.

4. I'm lazy. If I want to go my own way I have to tweak around with the code to get it formatted just how I like it. And/or I have to tweak around with the rules to make them fit what I like. I have to even have to think about and decide what I like first. Nah, much easier to just throw code at it, have rustfmt format it properly and do what clippy says. Job done. Next...

There is only one little niggle I have. Habitually I will write functions with return statements:

Code: Select all

fn () -> bool {
    ....
    return true;
}
In Rust the value of the last statement executed is the return value so we only need:

Code: Select all

fn () -> bool {
    ....
    true
}
But notice the lack of a semicolon there. If one puts a semicolon there, as I habitually do, we get a type mismatch error.
That extra semicolon introducs a new, empty, statment that returns an empty result instead of the bool required in this example.

Being a C head I find that a bit jarring and that seeing an actual "return" is clearer about what is going on.

Just for you I took out the option to allow camelCase and changed everything to snake_case as clippy suggested. Seems they like to use CamelCase for structs. All uppercase for static constants, like defined numbers and such in C. There is method in their madness.

It now looks like this:

Code: Select all

//
// insane-british-anagram-4.rs - Find words that have valid anagrams
//                               Words sourced from Debian's british-english-insane dictionary
//
// heater - 2019-08-05
//
// WARNING: This is not a good solution. Only a crazy experiment in trying to write Rust like C.
//          It's verbose, complex but marginally faster.

// LOOK AT:  Bare Metal WASM by Cliff L Biffle:
//           https://users.rust-lang.org/t/writing-a-213-byte-webassembly-graphics-demo-with-rust/29099
//           http://cliffle.com/blog/bare-metal-wasm/

use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::io::{self, Write};

#[derive(Copy, Clone)]
struct SliceSpec {
    begin: usize,
    end: usize,
}

#[derive(Copy, Clone)]
struct AnagramSet {
    word_slices: [SliceSpec; 17],
    size: usize,
}

impl AnagramSet {
    fn new(word: SliceSpec) -> AnagramSet {
        AnagramSet {
            // KEEP RETURN !
            word_slices: [word; 17],
            size: 1,
        }
    }
    fn push(&mut self, slice: SliceSpec) {
        self.word_slices[self.size] = slice;
        self.size += 1;
    }
}

fn read_insane_british_dictionary(mut dictionary: &mut Vec<u8>) -> std::io::Result<()> {
    let mut file = File::open("/usr/share/dict/british-english-insane")?;
    file.read_to_end(&mut dictionary)?;
    Ok(())
}

fn is_lower_case(c: u8) -> bool {
    !(((c as char) < 'a') || ((c as char) > 'z'))
}

fn output_anagrams(
    index: &[u64],
    anagram_map: &HashMap<u64, usize>,
    anagram_sets: &[AnagramSet],
    dictionary: &[u8],
) {
    let stdout = io::stdout();
    let mut stdout_handle = stdout.lock();

    let mut output: String = "".to_string();
    for hash in index {
        if let Some(anagram_sets_count) = anagram_map.get(&hash) {
            let size = anagram_sets[*anagram_sets_count as usize].size;
            if size > 1 {
                let mut separator = "";
                let mut i = 0;
                while i < size {
                    let begin = anagram_sets[*anagram_sets_count].word_slices[i].begin;
                    let end = anagram_sets[*anagram_sets_count].word_slices[i].end;
                    let slice = &dictionary[begin..end];
                    let word = String::from_utf8_lossy(&slice).to_string();
                    output += separator;
                    output += &word;

                    if i == 0 {
                        separator = ": ";
                    } else {
                        separator = ", ";
                    }
                    i += 1;
                }
                output += "\n";
            }
        }
    }

    match stdout_handle.write_all(output.as_bytes()) {
        Ok(()) => {}
        Err(e) => println!("Error writing reult {}", e),
    }
}

fn find_anagrams(
    index: &mut Vec<u64>,
    anagram_map: &mut HashMap<u64, usize>,
    anagram_sets: &mut Vec<AnagramSet>,
    dictionary: &mut Vec<u8>,
) {
    let mut anagram_sets_count: usize = 0;
    let mut word_index = 0;
    let mut character_index = 0;
    let mut reject = false;
    let mut hash: u64 = 1;

    for c in dictionary {
        if is_lower_case(*c) {
            // We are scanning a valid word
            let prime_index = (*c - 97) as usize;
            hash = hash.wrapping_mul(PRIMES[prime_index]);
            character_index += 1;
        } else if *c as char == '\n' {
            // We have hit the end of a word, use the word if it's valid
            if !reject {
                // Do we have a word with this key (potential anagram)?
                let word_spec = SliceSpec {
                    begin: word_index,
                    end: character_index,
                };
                match anagram_map.get_mut(&hash) {
                    Some(anagram_sets_count) => {
                        // Found: Append it to the existing anagram set
                        anagram_sets[*anagram_sets_count].push(word_spec);
                    }
                    None => {
                        // Not found: Add it to the map as start of new anagram set.
                        // Make a new anagram set with one word in it.
                        let anagram_set = AnagramSet::new(word_spec);
                        // Add the new anagram set to our list of anagram sets
                        anagram_sets.push(anagram_set);
                        anagram_map.insert(hash, anagram_sets_count);
                        anagram_sets_count += 1;

                        // And add the new anagram set to index
                        index.push(hash);
                    }
                }
            }
            character_index += 1;
            word_index = character_index;
            hash = 1;
            reject = false;
        } else {
            // Invalid character
            hash = 1;
            reject = true;
            character_index += 1;
        }
    }
}

// One prime number for each lower case letter of the alphabet
static PRIMES: [u64; 26] = [
    2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
    101,
];

fn anagrams() {
    // Container for sets of anagrams
    // An anagram set is simply an array of offets into the anagram_sets array
    let mut anagram_map: HashMap<u64, usize> = HashMap::new();

    // Vector of AnagramSets
    let mut anagram_sets: Vec<AnagramSet> = Vec::new();

    // An ordered index of anagram set keys
    let mut index: Vec<u64> = Vec::new();

    let mut dictionary = Vec::new();

    match read_insane_british_dictionary(&mut dictionary) {
        // Takes 25ms on PC
        Ok(()) => {
            find_anagrams(
                &mut index,
                &mut anagram_map,
                &mut anagram_sets,
                &mut dictionary,
            );
            output_anagrams(&index, &anagram_map, &anagram_sets, &dictionary);
        }
        Err(e) => {
            println!("Error reading dictionary: {}", e);
        }
    }
}

fn main() {
    anagrams();
}
Memory in C++ is a leaky abstraction .

jahboater
Posts: 5413
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 4:22 pm

Interesting! I assume you like it because it has "let" everywhere :)

Trivial point, does Rust promote integers like C does?
For example:-

Code: Select all

// One prime number for each lower case letter of the alphabet
static PRIMES: [u64; 26] = [
    2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
    101,
];
Seems awfully wasteful on space, seven/eighths of it is zero!
Could you give u8 instead of u64 like you would in C.

User avatar
Paeryn
Posts: 2900
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 5:04 pm

Sorry I mis-interpreted your meaning, this hot weather is getting to me.

I agree with the niggle about requiring the final line to not have semi-colon when returning a value. I'm used to having the last thing in a function being the return value from functional languages so not having a return keyword isn't too strange.

I like their separation of case usage, I generally do similar in C where I start type names with capitals but variables with lower case.

Wouldn't your while loop in output_anagrams

Code: Select all

    let mut i = 0;
    while i < size {
        ...
        i += 1
     }
be better written as a for loop?

Code: Select all

    for i in 0..size {
        ...
    }
Jahboater, no rust doesn't auto promote types, you have to explicitly do it.
She who travels light — forgot something.

ejolson
Posts: 4849
Joined: Tue Mar 18, 2014 11:47 am

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 6:16 pm

Heater wrote:Now I have to go though all my code and fix a hundred clippy warnings so as to keep the Rust style.
Is it possible cargo clippy is meant to be a joke based on the artificial intelligence of the same name from the Microsoft office suite?

I asked the canine coder whether FidoBasic enforced any particular formatting style for the source code. Fido replied that dogs don't like lint because it gets stuck to their fur coats. What about clippy, I furthered. The dog developer growled, clippy is for those scratchy cats with their retractable claws. That's what needs clipping.

With a whine that could only come from remembering an unfortunate experience, the developer continued, I even relaxed the formatting requirement in FidoBasic that line numbers must appear in numerically ascending order. Not impressed I interjected, other Basics have already done that. Then Fido became mad and barked, not with irrational line numbers. Relaxing the order requirement only makes sense because the line numbers used to denote different levels of meta programming have proved NP difficult to sort. After that Fido remained silent for some time scratching a bit of lint which had become lodged under the canine's collar.

It would appear that compiler-enforced formatting styles for Rust are so unpopular that they have been removed from the compiler and placed in a separate utility. This seems to go against the -Wall language-safety features present in many C and C++ compilers that presume most developers won't run lint unless it is conveniently built into the compiler.

Rather than minimising how talkative clippy is by replacing i=i+1 with i+=1, it might confuse the AI and thereby help avoid the digital apocalypse more effectively to maximise the number of warnings while keeping the semantic meaning of the code unchanged.

Wait a minute. With over one hundred warnings, could that be what you've already done? Hurray, the digital apocalypse is over!
Last edited by ejolson on Wed Aug 07, 2019 1:03 am, edited 3 times in total.

jahboater
Posts: 5413
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 7:55 pm

ejolson wrote:
Mon Aug 05, 2019 6:16 pm
[This seems to go against the -Wall language-safety features present in many C and C++ compilers that presume most developers won't run lint unless it is conveniently built into the compiler.
Originally, the compiler was intended to "compile" only and produce basic "syntax error" type messages, with absolutely no false positives.
Lint was allowed to produce "noise", that is it could speculate about what "may" be a problem. The two were quite different in purpose.
Later the complex and deep analysis required to produce decent diagnostics was found to be better done in the compiler - which had to do it anyway for optimization, so avoiding duplication of effort.

Thankfully neither lint nor -Wall would ever comment on "style", they are concerned only with safety and correct results.

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 8:30 pm

jahboater,
Seems awfully wasteful on space, seven/eighths of it is zero!
Could you give u8 instead of u64 like you would in C.
I agree. Looks wasteful.

So I played with it. Changing those constants to u8 and adding casting where required.

End result is that the binaries are exactly the same size!

Play with it yourself, as far as I can tell there is no point to changing it.
Memory in C++ is a leaky abstraction .

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 8:45 pm

Paeryn,
Wouldn't your while loop in output_anagrams ...
Good point.

Turns out that "for i in 0..size {..." is not only easier on the eyes but seems to be a few percent faster. I have not measured it rigorously but it's a win anyway.

Thanks for pointing it out.
Memory in C++ is a leaky abstraction .

Heater
Posts: 15340
Joined: Tue Jul 17, 2012 3:02 pm

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 9:08 pm

ejolson,
Is it possible cargo clippy is meant to be a joke based on the artificial intelligence of the same name from the Microsoft office suite?
Yep. I'm very sure that is true. I love the joke.

However in this case clippy does not need AI. It's working within the limited confines and rules of a programming language definition.

Even so I was amazed that it suggested using simple C style arrays rather than the C++ style Vectors I was using. And amazed it suggested an alternative to the "match" syntax I was using.

Anyway, at the end of the day, the source code may or may not look better for clippy's suggestions, it runs in the same time as before.
Memory in C++ is a leaky abstraction .

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Project Digital Apocalypse Not Now

Mon Aug 05, 2019 9:20 pm

I'm curious how the HASH method relates to the mathmatical approach being taken?

Return to “General programming discussion”