Filesystem links on different OSes
In most unix-style filesystems, files themselves are (inode,content) pairs, where inode is just a unique number for that filesystem
Directories are collections of (name,inode) entries.
That means you can theoretically have more than one directory entry to point to the same inode - two filenames pointing to the same stored data.
This is usually allowed, and such additional entries are called hardlinks.
- they are not really links at all.
- Yes, you can only really create the additional entries by referring to the first, but once they exist, they are all equal.
- Hardlinks were not usually called hardlinks until symlinks existed. (verify)(verify)
- since inodes are unique only per filesystem, hardlinks cannot point to things on other filesystems.
- Since that's extra bookkeeping (in particular "only delete contents after there are 0 directory entries resolving to this inode"), a filesystem has to implement this specifically.
- There are some that don't implement/allow it, but most filesystems that have POSIX in their background will.
- they arguably make the file analogy a little leaky, in that if you see two different directory entries, you don't expect that editing one will also change the other
Symlinks (sometimes 'softlinks') are, instead, a special type of directory entry.
On a low level these entries just store a path string (in early implementations in the file data, now optionally in the metadata as that's faster), and all file APIs know about this, meaning that if they meet a directory entry marked as a symlink, they will interpretet this as a kind of proxy/redirect, in that they resolve what they point to, and then open that.
Symlinks will work across across filesystems, because they use path strings instead of inodes.
For the same reason, it is not necessarily valid at all times, e.g. when you delete the file it points to. There is no related filesystem bookkeeping.
- you can have a stat() call stat the symlink entry or its target.
- Symlinks do not have permissions themselves, they always appear as lrwxrwxrwx, and these permissions are not used.
- Typical use just lands on the permissions of the target entry
- access to the symlink itself (e.g. to alter it) is based on the permissions on the directory it is in(verify).
- It is possible for a symlink to point to something that doesn't exist.
- interesting detail to symlinks and trailing slashes. Consider:
rm symlinktodir #removes the symlink rm symlinktodir/ #implies the directory pointed to
- If you meant to remove the symlink, but you added -rf out of (bad) habit, and path autocompletion added the slash, then you might've just thrown away a lot of data.
- A symlink path may be relative or absolute
- Absolute can be a little more secure, but potentially more fragile.
- Consider e.g. what happens when the target is replaced or the symlink is moved around.
- symlinks break the abstraction of trees, in that
- typical use makes the filesystem a dag, rather than a tree
- symlinked directories now have multiple absolute paths that point to them
- symlinked directories (arguably) now have multiple parents (so cd .. i)
- It is possible for a symlink to create loops in the filesystem.
- symlinks are more fragile in some (unusual) contexts
- consider what happens when you present directories outside of their context (e.g. chroot, over network filesystems) - that changes how symlinks should be resolved?
Notes that address both
While there are clear technical differences, in practice there isn't much you can do with hardlinks that you can't do with symlinks.
There are practical details and security issues to both. For example, consider the combination with a chroot jail - symlinks won't work, hardlinks give access to content that is outside the jail.
NTFS reparse point (introduced in NTFS 3.0, with Windows 2000)  are basically a way of saying "this directory entry needs to be handled in a special way".
It will havea reparse tag, plus data to be interpreted
The value in the reparse tag implies the which filter driver should be interpreting it
Since their introduction, then quite a few reparse tags have appeared, and for varied uses (e.g. some DFS stuff, some drive management in servers, caching in IIS, syncing protocols, metadata to launch UWP apps, and more).
In the context of regular-looking localish links, the more interesting are:
- volume mount points
- like *nix mounts, where the root of another filesystem can be placed under a specific path (rather than a specific drive letter)
- does not allow UNC paths(verify)
- directory junction points
- point to a directory within another volume, rather than its root (but actually implemented with the same tag as volume mount points)
- NTFS symbolic links 
- can point to either files or directories (decision at link time)
- can be relative paths, and UNC paths (so e.g. SMB network paths) (but apparently requires support by the remote host as well?(verify))
- added in NTFS 3.1 (around XP) but were never very easy to use
- WSL symlink
- not sure yet how this is different, but it's different.
- Probably related how there are also WSL domain sockets, named pipes, character and block device types.
- WCI links
- MS does containers now, so needed to add more secure isolation. This is part of that.