I'm seeing a lot of solutions to these Leetcode LinkedList problems involve creating a dummy node, e.g.
Example
It seems to me that constructing this one additional ListNode object isn't a big deal and more importantly, considerably simplifies code. However, in my school, creating this kind of additional object is SEVERELY penalized.
I'm just wondering, is creating this extra dummy node acceptable in actual industry work? It makes code a lot more concise, yet is technically using extra resources
is creating this extra dummy node acceptable in actual industry work?
Yes. Although there aren't that many examples I can think of where you would use linked lists in production code and would have to implement the linked list data structure yourself (as opposed to using an implementation provided by the programming language or a standard library that comes with it).
It makes code a lot more concise
Yes
...yet is technically using extra resources.
Yes, but not more than when you would use two additional variables in your code. So this is not really an issue. A dummy node represents O(1) auxiliary space, which is what you would use anyway for iterating through a linked list using a node pointer/reference.
in my school, creating this kind of additional object is SEVERELY penalized.
Too bad.
Using non-deterministic functions is unavoidable in applications that talk to the real world. Making a clear separation between deterministic and non-deterministic is important.
Haskell has the IO monad that sets the impure context by looking at which we know that everything outside of it is pure. Which is nice, if you ask me, when it comes to unit testing one can tell which part of their code is ultimately testable and which is not.
I could not find anything that allows separating the two in F#. Does it mean there is just no way to do that?
The distinction between deterministic and non-deterministic function is not captured by the F# type system, but a typical F# system that needs to deal with non-determinism would use some structure (or "design pattern") that clearly separates the two.
If your core model is some computation that does not interact with the world (you only need to collect inputs and run the computation), then you can write most of your code as functional transformations on immutable data structures and then invoke these from some "main" I/O loop.
If you're writing some highly interactive or reactive application then you can use F# agents (here is an introductory article) and structure your application so that the non-determinism is safely contained in individual agents (see more about agent-based architectures)
F# is based on OCaml, and much like OCaml it isn't pure FP. I don't believe there is away to accomplish your goal in either language.
One way to manage it could be in making up a nominal type that would represent the notion of the real world and make sure each non-deterministic function takes its singleton as a parameter. This way all dependent functions would have to pass it on along the line. This makes a strong distinction between the two at a cost of some discipline and a bit of extra typing. Good thing about this approach is that it can verified by the compiler given necessary conditions are met.
As we know Microsoft introduced the dynamic type a long time ago. And I also applied it in some case in the ASP.NET MVC application. But to me, it is not good for all cases. In specific, it's seen to be violating some basic principals like The Acyclic Dependencies Principle. For example, I have a package A that using package B, then in B I use dynamic and reference to A. It work fine. So the question is how do I use the dynamic type in correct way?
Speaking from experience: don't do it. Seriously, sooner or later you will regret.
Each time I decide to use dynamics I found it was a mistake. Using dynamics makes refactoring a nightmare, and you lose the biggest advantage which is type safety. Errors will show up in runtime instead of during compilation.
It's usually ten times better to refine your design and use oop principles or try to find some common interfaces.
It should be used only to simplify working with dynamic languages such as java script. Otherwise it is bad for your program performance and your mind sanity :)
So the best practice with dynamics is: try avoiding using them
Dynamic is not a type, it's syntactic sugar. The type will be object, but the compiler will put in a lot of code to detect the actual type of the variable at runtime.
It's meant to be used when you don't know the actual type, for example is used by the dynamic languages running on top of .Net.
It can be abused, as a lazy shortcut (but for that use var ) but you'll get a performance penalty in that case. Long story short, it should be used when you can't solve a problem easily with strong typing.
I think the dynamic keyword is good, but we have to using it very careful, like Mike mention as above. I used it on some small examples. When we use it, and we know it, so when somebody call to it, he/she have to know what kind of object that use in dynamic. Hope this help.
Is it fair to say that the following statement is not exactly correct, considering that in procedural programming you can have local scope?
"In procedural program, data is exposed to the whole program whereas in OOPs program, it is accessible with in the object and which in turn assures the security of the code."
(I'm a student and I was asked this question at an interview for an internship)
I agree with Mark, the part that isn't exactly correct is the "assures the security of the code".
An Object Oriented language is, under the hood, doing the same thing a procedural language could be doing: hide type definitions and then pass a pointer to a struct containing data vs. using a global. An example is C's pthreads library, which uses opaque types to prevent users of the API from modifying internal data structures. (Opaque just means the struct is defined in a private header, so the user can't see inside it without pointer tricks.)
But data security? No, because you can still use pointers to peak inside opaque structs and even to inspect data on the stack. This works in C++ too. A hacker can still attempt to examine a program's memory too (debugger, core dump, other tricks).
Pointers can be still used in pascal and i think they may preserve it until delphi is alive.
Even though i have used pointer when i am learning pascal. I still can't understand the real use of pointers, I manage to do all my delphi programs without it.(by some other ways)
what is the real use of pointers. And I am asking for real world usage, and can we manage to do anything without pointers.
You use pointers a lot more often than you think you do in Delphi. The compiler just hides it.
var
SL: TStringList;
...
SL := TStringList.Create;
// SL is now a pointer to an instance of the TStringList class.
// You don't know it because the compiler handles dereferencing
// it, so you don't have to use SL^ . You can just use the var.
SL.Add('This is a string');
A string is also a pointer to a block of memory that stores the string. (It actually stores more than that, but...)
So are instances of records, PChars (which is a pointer to a character array, basically), and tons of other things you use every day. There are lots of pointers that aren't called Pointer. :)
the pointers contain the address of a memory location, because that are present everywhere. each variable which you declare, even the code which you write can be accessed using a pointer, the pointers is one of the most essential elements in Win32 programming, you must read this great article from Rudy Velthuis Addressing pointers to understand the pointers usage.
To understand what pointers might be used for in modern day Delphi, one needs to understand how pointers have been historically used and how Delphi uses pointers behind the scenes.
Pointers to code
One can have a pointer to a piece of code. This can be used for the intuitive thing (parameterizing some algorithm with the functions it needs to call; example: TObjectList.Sort takes a function pointer as a parameter). Modern Delphi uses pointers-to-code to implement the following (without going into details):
Virtual Method Tables; We can't have OOP without VMT's
Interfaces
Events and anonymous methods.
Those are all very powerful methods of avoiding raw pointers to code, indeed there's very little need for raw code pointers today.
Pointers to data
Everybody learned pointers using the Linked Lists. Pointers are essential in the implementation most non-trivial data structures; In fact it's hard to name a useful data structure that's not implemented using pointers.
Delphi gives lots of grate abstractions for data pointers, so we can work without ever touching an pointer. We have Objects (class instances) and good implementations for most data structures (string, TObjectList, dynamic arrays).
When do we use Pointers?
We essentially use pointers to implement more of the grate stuff that Delphi provides for us. I can give examples of what I've used pointers for, but I find it more interesting to give examples of what others have used pointers for:
TVirtualTree: Makes good use of pointers to data.
Pascal Script for Delphi: Makes extensive use of raw pointers to code!
Let's start with a definition, taken from Wikipedia:
A pointer is a programming language
data type whose value refers directly
to (or "points to") another value
stored elsewhere in the computer
memory using its address.
All computers address memory and to do so the machine language that they execute must do so using pointers.
However, high level languages do not need to include pointers explicitly. Some examples of those that do not are LISP, Java, C#, Perl, Python, but there are many more.
I'm interpreting your question to be why languages support explicit pointer use, since all languages use pointers implicitly.
Delphi descends from Pascal which is a rather primitive language when viewed from the 21st century. Pascal pointers are the only way to use references. In modern Pascal derivatives, e.g. Delphi, have many types of data that are reference based, but implicitly so. For example I'm thinking of strings, object instances, interfaces and so on.
It is perfectly possible to write any program in Delphi without resorting to explicit pointers. The modern trend away from explicit pointers is down to the observation that explicit pointer code is more prone to errors than the alternatives.
I don't think there's any real reason to carry on using explicit pointer code in Delphi. Perhaps very time critical algorithms may push you that way, but I'm really struggling to think of anything that is significantly better implemented with pointers than with the alternatives.
Personally I avoid using explicit pointers wherever feasible. It generally makes code easier to write, verify and maintain, in my experience.
1) Classes are pointers. Strings are pointers. The compiler pretty much hides this from you but you do need to understand this when debugging.
2) Any sort of tree structure needs pointers.
I use a lot of custom data structures in my programs (for instance, in my own scripting language /interpreter/, where I store the structures, or "records", used in this language - these can contain other records and the nesting is unrestricted). I do this at the very lowest level, namely, I allocate a number of bytes on the heap, and then I read, parse, and write to these completely manually. To this end, I need pointers to point to the bytes in the allocated blocks. Typically, the blocks consists of "records" that reference each other in some ways. In addition, many of these structures can be written to file (that is, I have also designed my own binary file formats), simply by copying from the heap (in RAM) to the disk byte-by-byte.
Pointers (memory addresses) are a basic CPU type to access memory. Whatever language you use to write an application, when it comes to the CPU it has to use "pointers" to work.
Thereby they are a low-level type which allows a huge degree of versatility, at the price of a somewhat more complex management and the risk of accessing or writing the wrong memory if not used correctly.
You could let a language translate your data to pointers and memory buffers, or use pointers directly if the language allows for it. Being able to do it allows for direct and optimized memory access and management.
I thought I could add my salt to the soup, but the answers above say it mostly all. There's one more thing though. I remember being scared when I saw all those referencing and dereferencing operators (in different languages) and all the magic that was done with pointers. I didn't dare to look the devil in the eye for YEARS. I preferred to ineffectively copy data instead of going down the pointer path.
Today though, I do love pointers. Working with pointers makes you aware of what happens under the hood. And it makes you aware of the memory you are playing with (responsibly). Practically it allows you to code more effitiently and consciously! Last but not least it turns out to be quite fun to play with such simple but powerful toys.