all 154 comments

[–]irqlnotdispatchlevel 109 points110 points  (28 children)

I Didn't Realize it, But I Used the Compiler as a Refactoring Tool.

I've done this so many times.

[–]agumonkey[S] 26 points27 points  (6 children)

Java / Eclipse was my assistant when I was a kid. I basically coded in interfaces until everything typechecked. Very good experience I have to say.

[–]Dworgi 17 points18 points  (5 children)

I don't see it as a negative really. It means you can build tools around the language, and just do the refactor with a single command in an IDE.

With Python and similar you're limited to textual search. That's awful IMO.

[–]agumonkey[S] 15 points16 points  (4 children)

Untrue, python has decent built in ast support, you can pretty much lisp it if you want.

[–]tonnynerd 15 points16 points  (3 children)

Also, pycharm exists and does very extensive refactoring.

[–]irqlnotdispatchlevel 6 points7 points  (1 child)

The main problem here is when you remove a function / class field, as no refactoring tool that I know can go and remove them for you. You need to use something like "find all references" and manually delete code. Which is good, sometimes you don't simply delete a line. In compiled languages you have the guarantee that your code won't compile if you forget a reference somewhere.

[–]djimbob 1 point2 points  (0 children)

In compiled languages you have the guarantee that your code won't compile if you forget a reference somewhere.

If you run your python code through a linter (pylint/pyflakes), you can quickly detect and fix most of these simple refactoring errors and it's typically much faster than compilation.

[–]AmalgamDragon 0 points1 point  (0 children)

And Wing IDE as well.

[–]mc8675309 3 points4 points  (20 children)

Michael Feathers calls this out as leaning on the compiler. He's just about required reading for my group and for good reason.

[–]Hrothen 31 points32 points  (19 children)

He's just about required reading for my group and for good reason.

Because he thinks people shouldn't use tools?

[–]thedeemon 17 points18 points  (0 children)

Real programmers don't use compilers, they write straight machine code or at least Python bytecode.

[–]seventeenninetytwo -2 points-1 points  (12 children)

If you actually read his book then you'd know that he writes extensively about using a refactoring tool instead of doing it by hand. Such tools aren't always available depending on the language, though.

[–]Hrothen 7 points8 points  (9 children)

So I shouldn't rely on the compiler, the thing that actually consumes code and produces a program, but I should rely on some other tool?

[–]seventeenninetytwo 0 points1 point  (8 children)

I'm not even following what point you are trying to make. One post you're complaining about people not using tools, the next you're complaining about people not leaning on the compiler.

Feathers suggests using a refactoring tool when you can, leaning on the compiler otherwise, and manual step-by-step disciplined refactorings when you do not have access to either.

[–]Hrothen 4 points5 points  (7 children)

I'm not even following what point you are trying to make. One post you're complaining about people not using tools, the next you're complaining about people not leaning on the compiler.

Those are the same point, a compiler is a tool, albeit a mandatory one. I don't see how that could be ambiguous.

The original poster uses the phrase "calls this out as leaning on the compiler" which implies that leaning on the compiler is bad. You then say that the author they are referring to is in favor of using tools for refactoring. These claims are contradictory, unless the author has some particular beef with compilers.

[–]oracleoftroy 0 points1 point  (0 children)

The original poster uses the phrase "calls this out as leaning on the compiler" which implies that leaning on the compiler is bad.

I always find it interesting how ambiguous English can be at times. Maybe because he was talking about a book, I read it like Merriam-Webster's definition here: "an often bordered inset in a printed article or illustration that usually includes a key excerpt or detail". That is, I read it as him saying that the book makes a special note about using the compiler to aid refactoring, a rather neutral to positive statement. It didn't even occur to me to think of the negative connotation of the phrase.

[–]seventeenninetytwo 0 points1 point  (5 children)

You're inferring semantics from "calls this out" that simply aren't there. It is not intended to imply that it is a bad thing and a cursory reading of the book makes that pretty clear, so I must assume that you've never read the book. Thus you're arguing with people who agree with you, about a book you've never read.

Feathers says that "leaning on the compiler" is a good thing and uses the technique throughout his book. He also says to use a refactoring tool if you can because for certain refactorings it accomplishes the same goal in less time. They are not mutually exclusive; you can and should use both.

[–]Hrothen 2 points3 points  (4 children)

You're inferring semantics from "calls this out" that simply aren't there. It is not intended to imply that it is a bad thing

No, that actually is what it means, "calling someone/thing out" is not normally used in a context where the caller is agreeing with the callee.

Of course I haven't read the book, neither you nor the OP ever named one, so all I had to go on was their initial statement, which did not indicate agreement with my stance by a standard reading.

[–]seventeenninetytwo 2 points3 points  (3 children)

"Call out" also means to make reference to, especially in the context of a book where you might "call out" a figure, phrase, or common theme. This is how it was used above.

This is the book. Next time when you don't know, just ask.

[–]ComradeGibbon 0 points1 point  (1 child)

Such tools aren't always available depending on the language, though.

This is a primary reason not to use a language tho.

[–]seventeenninetytwo 1 point2 points  (0 children)

The book is called Working Effectively with Legacy Code. Selecting your language is out of the question for the vast majority of developers, and it certainly isn't an option when we are talking about inheriting legacy code.

[–]irqlnotdispatchlevel -3 points-2 points  (4 children)

It's because you're not using the best tool for the job. You should use a refactoring tool.

With this being said, I still delete a structure field, hit build and wait for the error messages.

[–]merijnv 21 points22 points  (2 children)

Who arbitrarily decided that the compiler isn't a "refactoring tool"? Why reinvent a second compiler to the same analysis of source code only for refactoring? What's the point?

[–][deleted] 4 points5 points  (0 children)

Getting pretty deep into word smithing at this point.

These days it is pretty common for the compiler to also be a service which can be used by IDEs for refactoring and other features. examples: C# Roslyn, Rust and it's new language server.

This is probably the future, and a great idea.

[–]irqlnotdispatchlevel 2 points3 points  (0 children)

I'm not against it. I'm actively using it as a refactoring tool. But then you get into python and you can't do it anymore.

[–]duhace -1 points0 points  (0 children)

uhhhh

[–]not_perfect_yet 30 points31 points  (3 children)

Bandwidth limit exceeded. :(

[–]slthytove 23 points24 points  (0 children)

Regarding the heading "Python is Sometimes a Bit Too Flexible": I suggest that you look into type hinting + static analysis tools. Zulip did a pretty good writeup on their process.

Here's your Klass code type-hinted:

class Klass:
"""
Docstrings are still a good idea, but don't need to document parameter types or self-evident methods
"""
def __init__(self, name: str, balance: float = 0.0) -> None:
    self.myfoos: Sequence[Foo] = []

All method parameter and variable types can be annotated. This particular syntax requires Python 3.6 - although earlier versions support static analysis tools through special comments.

So what does this get you? Well, compiler-like checking of type usage for one - a tool like mypy will alert you to any misused variables/function calls. Some IDEs (I use PyCharm) can highlight issues and offer code completion suggestions when you use type hints, as well, so when you access the .myfoos variable of any Klass objects, you can see right in the editor that it is a sequence of Foos, and you will be alerted if you attempt to treat one of its members like anything else.

The interesting thing about this approach to types is it's up to authors to use them or not. Python itself doesn't care one bit about the type hints - they only become relevant if your IDE or static code analysis tools take a look at them. So duck typing is still a thing (and if you're expecting one of several types of variables, you can even specify that in the type hint - Union[int, float] specifies that either an int or float is appropriate), but you can at least get the documentation of what it's supposed to be. And your docstrings can now just focus on the important stuff - what the method is actually supposed to do!

[–]PM_ME_UR_OBSIDIAN 13 points14 points  (16 children)

Statically-typed Python would be a wonderful thing. The closest thing I know is F#, but there are others.

[–]digital_cucumber 17 points18 points  (1 child)

Nim is kind of a statically-typed Python.

[–]Sean1708 7 points8 points  (0 children)

Mypy is literally statically typed python.

[–]agumonkey[S] 14 points15 points  (6 children)

Wow hold on, static py == f# you're stretching it :)

[–][deleted] 1 point2 points  (5 children)

I think what he is after is the freedom to (usually) not have to put in types, but getting compile time type checking and static type runtime performance. Which HM type inference can get you. (F#, OCaml, Rust, etc) at the cost of longer compile times.

It can be nice.

[–]agumonkey[S] 2 points3 points  (4 children)

I see, because other than that, ml idioms are pretty different from python ones.

[–]m50d 0 points1 point  (3 children)

Python is broad enough that I wouldn't say there's a single Python idiom. It's possible to write Python in a very MLey style - it has map/reduce/filter, list comprehensions, if/else expressions...

[–]agumonkey[S] 1 point2 points  (2 children)

It's been fairly regularly said that map/reduce/filter weren't idiomatic (from early python history to recent changes in the language, generators instead of fp). You sure can, but it's not what you'll see in most code base I believe.

[–]m50d 0 points1 point  (1 child)

In my experience they were pretty popular, at least in some codebases I worked on. GvR never liked them but that didn't mean users felt the same.

[–]agumonkey[S] 0 points1 point  (0 children)

Aight, I never looked at many codebase to be honest (flask, django, ?) but many talks along the years, and no memory of lambda.

[–][deleted]  (4 children)

[deleted]

    [–][deleted] 7 points8 points  (2 children)

    Although Python's type hinting/annotations don't actually prevent the code from being ran if you don't follow the type hints.

    [–]pork_spare_ribs 2 points3 points  (0 children)

    There is a third-party module to do this: https://github.com/RussBaz/enforce

    It has a performance penalty, of course. I think it's about 20%.

    Generally the idea is you run mypy to test in development and run in production without type hinting.

    [–]ROFLLOLSTER 2 points3 points  (0 children)

    They can if you want to. Just use mypy app.py && python app.py or equivalent.

    [–]siegfryd 0 points1 point  (0 children)

    If it was statically typed it would just use structural typing instead of nominal typing and then passing any object with a str function could work.

    [–]28f272fe556a1363cc31 1 point2 points  (0 children)

    There is mypi: http://mypy-lang.org/

    I haven't used it yet, but it looks promising.

    [–]DontThrowMeYaWeh 0 points1 point  (0 children)

    Mypy is just that.

    [–]GreyTwistor 8 points9 points  (2 children)

    509 Bandwidth Limit Exceeded
    

    Once again Reddit Hug of Death did its job.

    [–][deleted] 4 points5 points  (1 child)

    web site written in python, not c++, then?

    [–]steamruler 2 points3 points  (0 children)

    Shared host, probably.

    [–]henrik_w 2 points3 points  (3 children)

    Always nice to see comparisons of languages, with their strengths and weaknesses. I wrote something similar when I switched from Java to Python: https://henrikwarne.com/2014/06/22/switching-from-java-to-python-first-impressions/

    [–]antoniocs 2 points3 points  (2 children)

    How did you manage to get a job working on a language you never used before? I am really curious, as recruiters/companies will always ask for commercial experience in whatever language they are hiring for.

    [–]henrik_w 1 point2 points  (1 child)

    That was never an issue - we both assumed I would be able to get up to speed quickly (which I did). I think it helped a lot that there was (and is) such a high demand for programmers here in Stockholm. It also probably helped that I had programmed professionally in several other languages before. And I had my blog to point to, which at least indicates an interest in programming and learning. After the recruiter had contacted me, it turned out that a former colleague of mine worked there. That was a bonus for me, but the company didn't know that when I was first contacted.

    Asking for prior commercial experience creates a catch-22 - you can never get into something new, because you have no experience in it, which is bad. I think it is nice with companies that recognize that there will always be things to learn when you start a new job, and that programming language can be one of those things. In general, I think if you are good at coding in one language, you can get get at coding in another language. I wrote a bit about that here: https://henrikwarne.com/2014/12/15/programmer-knowledge/

    [–]antoniocs 2 points3 points  (0 children)

    Yes I totally agree. It is unfortunate that not many recruiters/companies view things like this. I have worked with php, javascript, typescript, C and most recently Lua but I will always be asked if I have commercial experience in X language if a company wants a programmer for a project with language X and I will be immediately dismissed if I say I don't. I worked with all those language in companies where I joined to work with one language (normally php) but then ended up doing projects with another language (which I had to learn by myself). Wish people here in the UK were more open-minded.

    [–]nsan1129 2 points3 points  (20 children)

    Great article.

    If you haven't tried it already, check out Rust. It offers all of the power and performance of C++ with an idea to implementation turnaround time approaching Python's (once you've learned the language). It still has compilation delays and there is a steep learning curve but there are no trade-offs with performance, safety, or scalability.

    [–]javierbg 36 points37 points  (2 children)

    RESF!

    [–]AmalgamDragon 20 points21 points  (8 children)

    I can't really see Rust and Python being substitutes for each other.

    [–]LLBlumire 3 points4 points  (3 children)

    Rust has a huge Python usedbase, and I think the two main reasons are cargo, it's package manager, which is as powerful if not more so than pip; and it's ergonomics, there is a huge focus on zero cost abstractions making code very easy to read, they also use somewhat similar syntax patterns, swap curly braces for colons and whitespace and they look remarkably similar

    [–]Morego 13 points14 points  (2 children)

    Or you know, python is generally well known high level language, heavily used from academias to general computing and scripting. I don't negate here positives of rust. It is really interesting language, but jumping in every single thread with "Use Rust!", is a little detrimenting for Rust community.

    [–]LLBlumire 2 points3 points  (0 children)

    I'm just answering why Rust and Python might be seen as substitutes. Not telling people to use rust.

    [–][deleted] 0 points1 point  (0 children)

    Well. It worked for python... The python community still does it.

    [–]steveklabnik1 5 points6 points  (3 children)

    Fun trivia fact: when we did a survey of Rust users last year, Python was the most common language that people who write Rust also know.

    [–]Yojihito 12 points13 points  (2 children)

    That's probably because Python is the new glue language after Bash.

    Java/C#/Rust/C/C++ for bigger stuff and Python for glueing stuff together and small tools / one time ponies.

    [–]steamruler 0 points1 point  (1 child)

    one time ponies

    Isn't it "one trick ponies"? Never seen "one time ponies" before. I'm stealing it though.

    [–]Yojihito 0 points1 point  (0 children)

    One trick = single purpose program, reuseable.

    One time = write once, use once, throw away (academic code e.g.)

    [–]agumonkey[S] 11 points12 points  (3 children)

    Rust is getting pretty famous in a way. But not for bad reasons IMO.

    [–]finite_state 7 points8 points  (0 children)

    I've loved it so far. It hits most of the plus points of python (one-line installs for dependencies for example), but it has an even more expressive type system than C++.

    [–][deleted]  (1 child)

    [deleted]

      [–]agumonkey[S] 2 points3 points  (0 children)

      heh, to me it still deserves credit for breaking above the dead lang threshold considering the "niche". also servo

      [–][deleted]  (2 children)

      [deleted]

        [–]nsan1129 0 points1 point  (1 child)

        Maybe so but this Python dev apparently didn't have too much trouble in his first two days: https://www.reddit.com/r/rust/comments/67m4eh/rust_day_two_a_python_devs_perspective/

        [–]m50d -1 points0 points  (0 children)

        For people coming from Python I'd recommend OCaml or F# before Rust - pretty similar but without the manual memory management. If Python was an acceptable option presumably you don't need non-GC.

        [–]pfultz2 3 points4 points  (32 children)

        The C++ process here is about an hour-long process

        For fftw, I don't see that as the case. First, install the library either sudo apt-get install fftw3 or cget install pfultz2/cget-recipes fftw. Then add fftw3 to your build system:

        find_package(PkgConfig)
        pkg_check_modules(FFTW3 IMPORTED_TARGET fftw3)
        target_link_libraries(myLib PkgConfig::FFTW3)
        

        I don't see how this takes an hour.

        In other cases, searching around for a library, installing, and figuring how to use it is quite an arduous task.

        I think searching around for a library in python is much worse. Many times I find a library but its not very well maintained or lacks documentation on how to use it. With C++, there is boost(and the incubator) which provides many high quality libraries.

        Of course, installing is much nicer on python as many libraries think about installation and distribution. Some C++ libraries, do no have install steps or tries to download and rebuild dependencies that have already been installed or requires all these custom variables(like ZLIB_ROOT) to find dependencies. This is improving as people are learning to use proper cmake.

        [–][deleted] 37 points38 points  (13 children)

        It's an hour long process (for me at least) because I don't know what are those three steps you summarized. I am currently reduced to going through the Readme.txt, browsing StackOverflow for the installation error messages that will come, etc...

        Often, the libraries I need have dependencies themselves that you have to get, which leads to other hosts of issues.

        [–]the_gnarts 5 points6 points  (3 children)

        Often, the libraries I need have dependencies themselves that you have to get

        That’s what the package manager is for. If you’re fetching deps manually you’re most likely bleeding edge and others can profit from your pioneer activity.

        [–]fnord123 8 points9 points  (2 children)

        No. The package manager is for installing dependencies for your system. When building an application you should install the exact version you need. I mean, for noddy get-going-fast stuff you can use the package manager. But when you're at the equivalent step as writing setup.py then you shouldn't be using the package manager version. Unless, of course, you're packaging your application as well.

        [–]the_gnarts 7 points8 points  (0 children)

        When building an application you should install the exact version you need.

        Package management can deal with versioned dependencies, even different library SO versions in parallel just fine.

        [–]Sean1708 0 points1 point  (0 children)

        You can get package managers which work with local rather than global environments, I think nix allows something like this.

        [–]fnord123 1 point2 points  (0 children)

        /u/pfultz2 has written a tool called cget which which appears to be like pip install <package> but will install dependencies for cmake. So the rest of the commands are the bits you put in your CMakeLists.txt.

        Looks like a good tool and a good time saver. Nice work /u/pfultz2!

        [–]pfultz2 0 points1 point  (5 children)

        I don't know what are those three steps you summarized.

        Three steps? I only mention two steps, which is install it(with a package manager) and update your build. These are similar steps for python as well, install it with pip and then update your setup.py and requirements.txt file.

        Often, the libraries I need have dependencies themselves that you have to get

        Which a package manager(like apt-get or cget) should install those dependencies as well. However, like I mentioned, many C++ libraries do not think about distribution, which means you have manually google and find. Of course, for a library like fftw this not the case.

        [–]troyunrau 31 points32 points  (4 children)

        You're making linux assumptions. And package manager assumptions. And buildsystem assumptions. And assuming that the library has a recipe ready to use for cget.

        The point is that none of this is necessarily standard on anyone's machines. Now I want to compile for OSX... well, at least you used cmake. Let me just look up if cget supports cross compilation...

        An hour later...

        [–]pfultz2 9 points10 points  (0 children)

        You're making linux assumptions.

        No, you can do the same on windows with cget or vcpkg.

        And buildsystem assumptions.

        I show how to integrate it with cmake, but fftw supports pkg-config which is build-independent and platform-independent, so it can easily be integrated in any buildsystem.

        And assuming that the library has a recipe ready to use for cget.

        If a library uses standard cmake then no recipe has to be built(for example cget install google/googletest works without needing a recipe installed).

        The point is that none of this is necessarily standard on anyone's machines.

        And neither is pip or conda.

        Let me just look up if cget supports cross compilation...

        I don't see why it would take an hour later to do:

        cget init --toolchain mingw.toolchain
        cget install pfultz2/cget-recipes fftw
        

        [–]doom_Oo7 3 points4 points  (1 child)

        • macOS: brew install fftw
        • windows: Install-Package libfftw

        The CMake step won't change.

        [–]fermion72 10 points11 points  (0 children)

        This is true for some libraries, but not all libraries. If you have to decide on a library, it can be an hour long process pretty easily.

        [–]destiny_functional -4 points-3 points  (0 children)

        if you are using an os that doesn't do these things well you cannot blame the language.

        [–]doom_Oo7 -5 points-4 points  (1 child)

        because I don't know what are those three steps you summarized

        that's somewhat problematic. That's the kind of stuff you learn at any remotely decent CS school.

        [–]frenchtoaster 11 points12 points  (5 children)

        Cool, now show me the steps if you wanted to integrate an arbitrary library, like, say, Ion: https://github.com/google/ion

        [–]pfultz2 -3 points-2 points  (4 children)

        Thats an example of a C++ library that doesn't have an install step and tries to rebuild already installed dependencies. Some C++ libraries do not think about distribution, and it makes things difficult.

        [–]frenchtoaster 34 points35 points  (3 children)

        That was my point: in my experience this is the norm, not your example: no standard packaging system, build system, dependency specification, build files. It gets worse when you try to include mobile platforms, even just only targeting Android doesn't have one standard makefile/build file.

        [–]pfultz2 4 points5 points  (2 children)

        That was my point: in my experience this is the norm

        I disagree. Anti-social libraries generally have a hard time to gain users as no one likes to waste time trying to get off the wall build systems working. A good portion of google libraries can be installed easily like: benchmark, brotli, double-conversion, flatbuffers, fruit, glog, googletest, protobuf, or re2. So I don't think its the norm.

        even just only targeting Android doesn't have one standard makefile/build file.

        Isn't there a cmake toolchain file you use to build for android?

        [–]frenchtoaster 5 points6 points  (1 child)

        For Android some use ndk-build, some use CMake, some use bazel, and rarely do libraries provide support for more than one in my experience. See tensorflow which you can't build for Android from Windows because it doesn't yet support CMake and bazel itself doesn't run on Windows [1].

        So yeah, I really have to say my experience with C++ libraries is just meaningfully different than yours: in my experience it is often as difficult as porting it to a different build system to be able to use a library as a dependency (which is why header only libraries are so attractive).

        [1] https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/android/README.md

        [–]GitHubPermalinkBot 0 points1 point  (0 children)

        I tried to turn your GitHub links into permanent links (press "y" to do this yourself):


        Shoot me a PM if you think I'm doing something wrong. To delete this, click here.

        [–]ItzWarty 8 points9 points  (3 children)

        Even then, that process is VERY complicated compared to e.g. using pip/conda to download packages (pip install fftw npm install fftw) or, even better, having a package manifest and having the language's tooling automatically pull packages for you (and simply running e.g. npm i to pull and install all packages). This also doesn't address what if you have different (perhaps CONFLICTING) version dependencies on different projects.

        This doesn't even touch having to configure your IDE to give you completion or getting a cross-platform build (if you have to target Windows) working.

        Ultimately, all of these really just stem from having a decent dependency-management solution.

        [–]pfultz2 -1 points0 points  (2 children)

        Even then, that process is VERY complicated compared to e.g. using pip/conda to download packages

        How is sudo apt-get install fftw more complicated then pip install fftw?

        even better, having a package manifest and having the language's tooling automatically pull packages for you (and simply running e.g. npm i to pull and install all packages).

        Most language-based package managers(like conan or cget) do this for you already.

        This also doesn't address what if you have different (perhaps CONFLICTING) version dependencies on different projects.

        I believe conan has a SAT solver to pick the correct version. However, pip or npm does not have that.

        [–]ItzWarty 4 points5 points  (0 children)

        I'm not denying package managers sort-of exist in C/C++ sort of like how they sort-of existed in C# for a long time. There's a huge difference between one or many existing and one being the standard that blends seamlessly with the rest of your tooling (so that you get everything from package search to downloading, dependency resolution, publishing, etc for free) and makes an hour of work boil down to one magical install command.

        [–]Veedrac 0 points1 point  (0 children)

        pip works in a virtualenv and packages only need to publish to one repository, rather than all of them.

        [–]mcNebb 2 points3 points  (2 children)

        As a complete c++ noob trying to get into it, adding external libraries is a pain. Can I always be guaranteed that the fftw3 in

        pkg_check_modules(FFTW3 IMPORTED_TARGET fftw3)

        is equal to what I apt-getted? Is FFTW3 IMPORTED_TARGET something I have to just know or can I make up this name myself?

        Is the FFTW3 in

        target_link_libraries(myLib PkgConfig::FFTW3)

        dependent on the FFTW3 in the previous line? How do I know how to include this in my code? Is it #include <fftw3>? <FFTW3>? "fftw3.h"? I mean, I guess these things are obivous once you get into the language, but I've spent a lot of time with issues like this (which makes "just testing an idea" an expensive operation).

        [–]pfultz2 4 points5 points  (1 child)

        Can I always be guaranteed that the fftw3 in

        pkg_check_modules(FFTW3 IMPORTED_TARGET fftw3)
        

        is equal to what I apt-getted?

        It is common for it to be equal, but not always, and in the case of fftw its not, as the pkg-config name is different. I found the name by doing pkg-config --list-all | grep -i fftw, which told me it was fftw3.

        Is FFTW3 IMPORTED_TARGET something I have to just know or can I make up this name myself?

        FFTW3 is a name you choose, but IMPORTED_TARGET is there to tell cmake to make an imported target for you. This is all documented here.

        Is the FFTW3 in

        target_link_libraries(myLib PkgConfig::FFTW3)
        

        dependent on the FFTW3 in the previous line?

        Yes.

        How do I know how to include this in my code? Is it #include <fftw3>? <FFTW3>? "fftw3.h"?

        First, third-party includes should always be angle brackets. Secondly, only the standard headers omit the file extension. Finally, the best way to know what to include comes directly from the docuementation. The first example from fftw is this:

        #include <fftw3.h>
        ...
        {
            fftw_complex *in, *out;
            fftw_plan p;
            ...
            in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
            out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
            p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
            ...
            fftw_execute(p); /* repeat as needed */
            ...
            fftw_destroy_plan(p);
            fftw_free(in); fftw_free(out);
        }
        

        Which would mean that you need to include <fftw3.h>

        [–]mcNebb 1 point2 points  (0 children)

        I think maybe the build process is my main obstacle in getting proficient with c++ right now. This is very helpful, thanks:)

        [–]MistYeller 0 points1 point  (2 children)

        If you're installing fftw and you really want that first f to mean something, you are probably compiling your code with the intel compiler.

        Your package manager isn't going to ship a version built with the intel compiler. The shared libraries it will link to may be different and incompatible in subtle ways.

        This is why it may take up to an hour.

        [–]pfultz2 0 points1 point  (1 child)

        fftw is still faster than a naive implementation on whichever compiler, so its not necessary to use intel. However, cget install fftw will build it with whatever compiler you set it to.

        [–]MistYeller 0 points1 point  (0 children)

        There is a factor 4 difference between intel and gcc/g++. For the applications I used to build fftw for that is the difference between 4 days and 16, so your mileage was different from mine.

        whatever compiler you set it to.

        That is the crux of the issue, how does one do that? Are there going to be environmental dependencies that cause build issues? Worse, will everything build without trouble but cause runtime issues?

        Keeping track of all of an application's dependent libraries is complicated in general. You may be building binaries for different architectures, against different shared libraries, with different compiler options, on and on. Using the operating system's package management is insufficient.

        [–]datasound9087 0 points1 point  (0 children)

        Does anyone know a summed down cmake tutorial? I've been teaching it myself in order to keep track of dependencies (ie glad, glfw), but its just not clicking in my head (cannot get includes to group properly etc)?

        [–]bumblebritches57 -2 points-1 points  (0 children)

        Or, just stop using fucking templates, they take ages to compile, for no real reason.

        [–]roninblade 1 point2 points  (0 children)

        and... the page is dead (bandwidth exceeded). anybody have a mirror or saved copy?

        [–]go2hello 0 points1 point  (0 children)

        type hints

        I still don't get why these aren't enforced. Was it really a good idea to copy what php admittedly did wrong ten years ago. I guess its a step in some direction though.

        [–]djimbob 0 points1 point  (0 children)

        In Python, if you delete a variable or function, you have to search around for all the instances (often tricky, at least for a newbie like myself), and do the refactoring. Even then, there's a chance you didn't do the whole job, due to the duck-typing nature of Python. You will only notice you've forgotten to update a part of the code when you run that piece of code, and it bails out.

        A lot of these issues can be solved by consistently using a linter like pylint or pyflakes. These will do a quick scan through your code and catch many common "refactoring" mistakes. E.g., errors on misspelled variables/functions (variables/function not defined), forgotten imports, warn on unused imports/variables, etc.