When comparing C vs Ruby, the Slant community recommends C for most people. In the question“What is the best programming language to learn first?” C is ranked 3rd while Ruby is ranked 10th. The most important reason people chose C is:
Learning C forces you to grapple with the low-level workings of your computer (memory management, pointers, etc.) in ways that the other languages abstract away. Without an understanding of these low-level aspects of computer programming you will be limited if you try to develop an application that needs to run in a memory or performance constrained environment. Other languages like Python can obscure a lot of details, so your foundation may be weaker.
Specs
Ranked in these QuestionsQuestion Ranking
Pros
Pro Understanding of computers
Learning C forces you to grapple with the low-level workings of your computer (memory management, pointers, etc.) in ways that the other languages abstract away. Without an understanding of these low-level aspects of computer programming you will be limited if you try to develop an application that needs to run in a memory or performance constrained environment.
Other languages like Python can obscure a lot of details, so your foundation may be weaker.
Pro Helps with learning other languages later
A lot of languages used in the industry have a C-like syntax (C++, Java, Javascript, C#, PHP) and starting with C will help new developers to be familiar with it's syntax and by extensions with the syntax of many popular languages.
Pro Industry standard
C is the industry standard programming language, moreover, it is the most popular programming language to use. C is the language used for most Windows, UNIX and Mac operating systems.
Pro Portable
C is portable between most hardware. Generally a C compiler is made for any new architecture, and already exists for existing architectures.
C is portable between all operating systems (Windows, UNIX, Mac, etc.) and only needs a program to be recompiled to work. This allows anyone on any operating system to learn about the language and not be held back by intricacies of their operating system.
With this said, C's portability these days is not quite what it used to be. Much of said portability relies on the POSIX standard in particular, and as time passes, the compliance of a given system with that standard is becoming less certain; especially in the case of Linux. Most things will still be portable (or at least emulatable) between Windows, Linux, and FreeBSD for example; but you will at times need to make use of platform-specific support libraries and APIs as well.
Pro Must-have
Capability to program in C is greatly appreciated in developers, creates an image of competency, and many programmers will learn it at some point in their careers.
Pro Low level of abstraction
While higher level languages languages like Java and Python provide possibilities to be "more expressive" per line of code, it's much more convenient to start with "less efficient" (get me right) language, in order to get initial concepts of how things behave at lower level.
Actually C is a good starting point moving to both higher and lower levels of abstraction, the good example here would be learning C before Assembler, as for general use the Assembler quite hard to understand due to low level of its abstraction (like getting the understanding on how loops work in C before trying to implement them on Assembler).
Pro More control over the code
Pro The king of languages, imitated, extended but never equalled
Made of a small set of keywords and rules, only your imagination is the limit. Above all, when it comes to 'pro' programming, C is the only one to rely on.

Pro Teaches good practices
Writing in C will require you to understand how things are done. C implies using and understanding the fundamentals. Learning a higher-level language after is much easier.
Pro Portable between CPU architectures
C was designed to be independent of any particular machine architecture, and so with a little care, it is easy to write "portable" programs (see here). By design, C provides constructs that map efficiently to typical machine instructions, and therefore it has found lasting use in applications that had formerly been coded in assembly language like operating systems or small embedded systems.
Pro C is simple with lesser rules than any other language
C is standardized and it is the go-to language when you have to speed things up.
Pro Ubiquitous
There is a C compiler available for probably every computer system in existence today.
Pro Easy to drop down to assembly
Sometimes you really need to program directly in assembly. C’s ABI and common compiler extensions make this a piece of cake.
Pro If you can't grok C you should not be a professional programmer
It sets an early bar that if you can't hurdle you might as well do something other than programming and not waste any more of your time.
Pro Basic concepts can be applied to accelerate learning any other language
You can easily pivot knowledge learned here and apply it to almost every other language.
Pro Foundational, difficult but important
Learning C will teach valuable skills and transferrable understanding of computing. While learning a scripting language may be easier, students will not understand system constraints and performance problems, nor what features like garbage collection are actually doing in other languages.
Pro Low level langauge
Pro Widely used
Ruby is one of the most popular languages for developing web sites. As a result, there's an abundant amount of documentation, sample code, and libraries available for learning the language and getting your project up and running. The most popular features are just 'gem install' away. Additionally, it is easier to find Ruby jobs because of this.
Pro Clean syntax
Ruby has a very clean syntax that makes code easier to both read and write than more traditional Object Oriented languages, such as Java. For beginning programmers, this means the focus is on the meaning of the program, where it should be, rather than trying to figure out the meaning of obscure characters.
presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"]
for ss in 0...presidents.length
print ss, ": ", presidents[presidents.length - ss - 1], "\n";
end

Pro A large ecosystem of tools & libraries
Ruby has a large ecosystem of tools and libraries for just about every use. Such as ORMs (Active Record, DatabMapper), Web Application Frameworks(Rails, Sinatra, Volt), Virtualization Orchestration(docker-api, drelict), CLI tools(Thor, Commando), GUI Frameworks(Shoes, FXRuby) and the list goes on. If you can think of it, there is probably a gem for that ( and if not you can create your own and share with the community).
Pro Newbie-friendly community
Pro Essential algorithmic features
The Ruby language is equipped with the necessary features to learn the essence of algorithms.
In online playground environments like ideone.com, measures have been taken to prevent beginners from going astray by restricting the use of external libraries such as Python's NumPy and SymPy.
Even in such constrained Ruby execution environments, the required features for learning algorithms are fully available.
Many of the algorithms that should be learned are documented in the book "Hello Ruby: Adventures in Coding." For example, the cake serving problem in the book leads to topological sorting, which is a graph theory concept useful in project management for creating Gantt charts.
To evaluate the effectiveness of algorithms with a level of complexity comparable to topological sorting,
it is necessary to be able to solve mathematical computation problems up to the high school level easily.
As shown in the table below, using only Ruby's standard library, it is possible to solve high school-level math problems effortlessly.
However, other programming languages may not be able to perform such computations in online playground environments.
To experience the superior performance of algorithms, it is important to challenge oneself by reimplementing good algorithms. Ruby's standard library includes implementations of excellent algorithms. For instance, the algorithm for solving linear equations, which has been widely known since the era of Fortran, is used within the code of SolvingLinearEquations through the "/" operator. Reimplementing code from Ruby's standard library serves as an excellent learning resource with high reusability and efficiency.
The SolvingLinearEquations function mentioned above demonstrates the benefits of duck typing and forced type conversion between objects of different types in arithmetic operations. While Rust also has features like duck typing, the implementation of "forced type conversion" is still far from being realized.
Mathematical Problem Type | Ruby Standard Library | Python Standard Library |
---|---|---|
Long Integer and Fraction | ✓ | ✓ |
Long Integer and Complex Fraction | ✓ | ✖ |
Operations on Matrices with Multiple-Digit Numbers as Coefficients | ✓ | ✖ |
Solution of Integer Coefficient Systems of Equations | ✓ | ✖ |
Solution of Systems of Equations with Long Integer and Complex Fraction Coefficients | ✓ | ✖ |
Solutions of Linear Equations with Real, Fraction, Complex, and Complex Fraction Coefficients | ✓ | ✖ |
# Title: "(1) Cake Serving Procedure Problem"
require 'tsort'
class Hash
include TSort
alias tsort_each_node each_key
def tsort_each_child(node, &block)
fetch(node).each(&block)
end
end
puts 'Tasks'
task_names = {
'A' => 'Arrange the plates.',
'B' => 'Set the spoons.',
'C' => 'Place the birthday cake on the table.',
'D' => 'Spread the tablecloth.'
}
p task_names
puts 'Preceding Tasks'
preceding_tasks = {
'A' => ['D'],
'B' => ['C', 'A'],
'C' => ['A', 'D'],
'D' => []
}
steps = preceding_tasks.strongly_connected_components
puts 'The appropriate steps are as follows:'
steps.each do |task_candidates|
p task_candidates.map { |task| [task, task_names[task]] }
end
p "#(2) Equation Solving Rule"
def SolvingLinearEquations(y, a, b)
x = (y - b) / a
end
p "(2-1) Real Solution", SolvingLinearEquations(1.0, 5, 0.5)
# => 0.1
p "(2-2) Fraction Solution", SolvingLinearEquations(Rational(1, 1), Rational(5, 1), Rational(1, 2))
# => (1/10)
p "(2-3) Imaginary Solution", SolvingLinearEquations(1 + 1i, 5, 1.0 / (2 + 2i))
# => (0.15+0.25i)
p "(2-4) Complex & Fraction Solution", SolvingLinearEquations(Rational(1 + 1i, 1), Rational(5, 1), Rational(1, 2 + 2i))
# => ((3/20)+(1/4)*i)
p "(2-5) Matrix Solution with Large Integers",
SolvingLinearEquations(Matrix[[Rational(1234567890123456789890, 1), Rational(0, 1)]],
Matrix[[Rational(1234567890123456789890, 1), Rational(1234567890123456789890 * 2, 1)],
[Rational(1234567890123456789890, 1), Rational(1234567890123456789890 * 3, 1)]],
Matrix[[Rational(1234567890, 1), Rational(123456789, 1)]] )
# => Matrix[[(3703703670366790122789/1234567890123456789890), (-2469135780244567900789/1234567890123456789890)]]
p "(2-7) Matrix Solution with Large Integers, Complex Numbers, and Fractions",
SolvingLinearEquations(Matrix[[Rational(1234567890123456789890, 1i), Rational(0, 1)]],
Matrix[[Rational(1234567890123456789890, 1), Rational(1234567890123456789890 * 2, 1i)],
[Rational(1234567890123456789890, 1), Rational(1234567890123456789890 * 3, 1i)]],
Matrix[[1234567890, 0 + 1i]] )
# => Matrix[[((-3703703671/1234567890123456789890)-(3/1)*i), ((2469135781/1234567890123456789890)+(2/1)*i)]]
Pro Ruby on Rails
Lays out an easy to follow and opinionated MVC pattern that teaches best practices through necessity.
Pro Test Driven Development, #1
It's the fore-runner and trend setter for TDD.
Pro Hugely object oriented
Object oriented programming is one of the most important concepts in programming.
Pro Meta-programming
Meta-programming provides efficiency and freedom.
Pro No indentation
No indentation increase development efficiency.
Pro Pry
Cons
Con Languages is full of corner cases and undefined behaviors
Undefined behavior in a program can cause unexpected results, making it hard to debug. With UB, program behavior may vary wildly depending on optimization settings. There are many cases that invoke UB, such as signed overflow, invalid dereferences, large integer shifts, uninitialized variables, etc. These serve to frustrate novice programmers when they could be learning other concepts.
Con Requires memory management
Learning programming is already hard enough when you don't have to worry about memory leaks.

Con Completely lacks type safety
The C standard library is not type safe, and the language itself does not promote type safety built into the language, which leads to error-proneness of the language. If anything, it would be recommended that those interested in C to instead put their time in D, which actually includes a complete copy of the C standard library rewritten to be fully type safe.
Con C will require you to learn concepts too advanced for most beginners
While other programmers will learn algorithms and structures and will do magic tricks and awesome applications, you will learn trash info that you should know maybe after 5-7 years experience in software development, not earlier. It's like going the first time as a seven year old kid to first school class, and your teacher tells you to learn you about Discrete Math, without basic math and how to do 2x2.
If you wish to be a really good programmer, C for sure will be in your portfolio, but not as a first language, and this programming language is used only for very hard and very limited tools which require a lot of professional skills from the programmer.

Con Does not support modules; header file annoyances
Header files are a poor man's implementation of modules. Modern programming languages make use of modules which eliminate the need for C includes and header files and the many issues caused by them, such as the complete lack of dependency checking. Header files often contain even more include statements that point to other header files which also point to even more which drastically increases compile time. Modules only have to be compiled once, and when importing those modules into your software project, you only have to pull in the module that you are using, which is often times already precompiled. This way, the compiler knows exactly what it needs before beginning to compile your project and can automatically compile the few dependencies it needs in advance rather than recursively compiling every header file it runs across as in C.
Con Steep learning curve
While the language compliments knowledge of computer components very well, and gives a deeper understanding, it is also quite difficult to learn, and to use correctly, especially without aforementioned knowledge.

Con Low-level
Depending on the purpose this can be either a pro or a con. If the task is to learn how to program, low-level of C will impend learning important concepts. Furthermore, C is rather limited in ways of building abstractions.
"Low-levelness" of C can be a pro feature in learning system programming.
Con Other languages can do it easier or better
There are languages like Rust, Object Pascal, D, Golang, Vlang, Odin, Zig, Jai, etc... that can be used instead. The other languages are easier to understand, use, and/or about as fast.

Con Compiles procedurally rather than intelligently
In the same manner that C recursively compiles header files ad infinitum without any sort of dependency checking, C source code is also compiled in the same manner. If you attempt to call a function before it is declared, the compiler will fail because the function was not compiled before it was caled.

Con Lack of support for first class strings
C does not support the string type, nor does it support UTF-8 strings that modern languages are employing today. Instead of strings, C makes use of the *char type which is a pointer to a character array.

Con Arrays are not first class objects
When an array is passed to a function, it is converted to a pointer, even though the prototype confusingly says it's an array. When this conversion happens, all array type information gets lost. C arrays also cannot not be resized, which means that even simple aggregates like a stack are complicated to implement. C arrays also cannot be bounds checked, because they don't know what the array bounds are.
Con Undefined behaviors and weak limited type safety
Subtle errors can render the entire program "undefined" by the complicated C standard. The standard imposes no requirements in such cases. Thus C compiler is free to ignore the existence of such cases and Bad Things are prone to happen instead. Even experts can't reliably avoid undefined cases in C, so how can beginners be expected to do so? C allows for non-type safe operations such as logic errors, wild pointers, buffer overflow, etc. UB and type safety issues create a large number of bugs and security vulnerabilities.

Con The need for C developers in the current market is very low, and trending downward
Older languages, like C, are no longer in their hay day. Even if you do learn it as your first language, you are only setting yourself up to need to learn another language in the long run. If you want a skill that you can not only learn from, but also potentially build a career on, C should not be your first choice.

Con Isn't truly portable or cross platform
The C programming language is not portable to other operating systems, and even different compilers, because the C language does not provide any reference cross platform libraries or compilers. Different platforms and compilers provide their own implementation of the C standard library which may not be compatible with the implementation in another compiler or platform. Without cross platform libraries and tools, one cannot state that C is portable. This is in stark contrast to modern programming languages that provide their own cross platform libraries and compilers, such as D, Go and Rust.

Con Only offers basic support for source code split into multiple files
Modern programming languages are capable of compiling split source code files by concatenating them together efficiently at compile time before compiling them. However, C requires the developer to resort to messing with header files and makefiles to get similar functionality.

Con C structs are very weak and outdated
C structs lack a lot of modern capabilities that are vital in programming languages of today, such as assigning member functions to structs to give them object-oriented capabilities, constructs, deconstructors and RAII. Great care must be used when using structs in C to prevent memory leaks and ridiculously slow structs.

Con Includes require obscene resources to compile
All the modern languages have resulted in ditching the ancient deprecated model of #include statements and have instead adopted the superior model of modules. When compiling software written in C, the programmer is forced to also compile X headers which contain Y headers which contain Z headers and so forth -- drastically increasing the number of lines that need to be compiled. In order to compile something as simple as "Hello, World", for example, 18K lines of code needs to be compiled. This can be very taxing on RAM and CPU resources, causing compile times to quickly absorb a large portion of the programming process.

Con Heavily outdated programming concepts
C lacks a large majority of programming concepts that modern languages make use of today. The existing functionality of C makes use of outdated and deprecated methodologies which can be of great annoyance to the modern day programmer.
Con Monkeypatching
Requiring a library can change the rules of the language. This is very confusing for beginners.
Con Its ecosystem is limited outside of web development
If you're looking to host, generate, manipulate or secure a website, Ruby is your language. There's also some great support here for infrastructure as code work via Chef. However, it just doesn't have the depth and breadth that Python does. Things like native UI development, high performance math, and embedded / small footprint environments are barely supported at all in Ruby-space.
Con Arcane grammar based on Perl
Ruby is too complicated for beginners:
- arcane Perlisms;
- semi-significant whitespace;
- parentheses are not necessary around method arguments, except for sometimes they are;
- control constructs could be elegantly implemented with block like Smalltalk (Instead they're baked into the grammar.);
- verbose block syntax, unless it happens to be the last argument. (proc lambda).
- There are too many exceptional cases and arcane precedence rules.
Con Meta-programming causes confusion for new developers
The ability for libraries to open classes and augment them leads to confusion for new developers since it is not clear who injected the functionality into some standard class.
In other words, if two modules decide to modify the same function on the same class can introduce a number of issues. Mainly, the order in which the modules are included matters. Since you more or less can't tell what kind of "helper" functions a module might write into any class, or for that matter, where the helper function was included from, you may sometimes wonder why class X can do Y sometimes but not at other times.
Con No docstrings
It's hard to access Ruby's documentation from the REPL (irb), unlike Python, Lisp, and Smalltalk which let you ask functions how to use them, which is a great benefit to the beginner, and which also encourages you to document your program as you code it.
Con More than one way to do it
A problem inspired by Perl. The core API interfaces are bloated. There's at least four different ways to define methods. More is not always better. Sometimes it's just more.
Con Does not teach you about data types
Since Ruby is a dynamically typed language, you don't have to learn about data types if you start using Ruby as your first language. Data types being one of the most important concepts in programming. This also will cause trouble in the long run when you will have to (inevitably) learn and work with a statically typed language because you will be forced to learn the type system from scratch.
Con Dynamic type system
Majority of bugs could be resolved with types.
Con Viewed as a web development language
Despite its flexibility and performance, Ruby is often seen as being unsuitable for other tasks by those who are not familiar with it. As such, a lot of discussion about it centers around Rails, which is not at all relevant if you're using Ruby for something else, such as game development.
Con Focus on Object-Oriented Programming (OOP)
Focussing on OOP in a beginner stage is an easy and popular plan, but not the best one.
